| author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> | 
| Fri, 22 Jan 2010 11:06:30 +0200 | |
| changeset 0 | 08ec8eefde2f | 
| permissions | -rw-r--r-- | 
| 0 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2 | ** 2001 September 15 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4 | ** The author disclaims copyright to this source code. In place of | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 5 | ** a legal notice, here is a blessing: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 6 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 7 | ** May you do good and not evil. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 8 | ** May you find forgiveness for yourself and forgive others. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 9 | ** May you share freely, never taking more than you give. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 10 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 11 | ************************************************************************* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 12 | ** This file contains C code routines that are called by the parser | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 13 | ** to handle SELECT statements in SQLite. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 14 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 15 | ** $Id: select.c,v 1.476 2008/09/23 09:36:10 drh Exp $ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 16 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 17 | #include "sqliteInt.h" | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 18 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 19 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 20 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 21 | ** Delete all the content of a Select structure but do not deallocate | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 22 | ** the select structure itself. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 23 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 24 | static void clearSelect(sqlite3 *db, Select *p){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 25 | sqlite3ExprListDelete(db, p->pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 26 | sqlite3SrcListDelete(db, p->pSrc); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 27 | sqlite3ExprDelete(db, p->pWhere); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 28 | sqlite3ExprListDelete(db, p->pGroupBy); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 29 | sqlite3ExprDelete(db, p->pHaving); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 30 | sqlite3ExprListDelete(db, p->pOrderBy); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 31 | sqlite3SelectDelete(db, p->pPrior); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 32 | sqlite3ExprDelete(db, p->pLimit); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 33 | sqlite3ExprDelete(db, p->pOffset); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 34 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 35 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 36 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 37 | ** Initialize a SelectDest structure. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 38 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 39 | void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 40 | pDest->eDest = eDest; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 41 | pDest->iParm = iParm; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 42 | pDest->affinity = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 43 | pDest->iMem = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 44 | pDest->nMem = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 45 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 46 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 47 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 48 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 49 | ** Allocate a new Select structure and return a pointer to that | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 50 | ** structure. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 51 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 52 | Select *sqlite3SelectNew( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 53 | Parse *pParse, /* Parsing context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 54 | ExprList *pEList, /* which columns to include in the result */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 55 | SrcList *pSrc, /* the FROM clause -- which tables to scan */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 56 | Expr *pWhere, /* the WHERE clause */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 57 | ExprList *pGroupBy, /* the GROUP BY clause */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 58 | Expr *pHaving, /* the HAVING clause */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 59 | ExprList *pOrderBy, /* the ORDER BY clause */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 60 | int isDistinct, /* true if the DISTINCT keyword is present */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 61 | Expr *pLimit, /* LIMIT value. NULL means not used */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 62 | Expr *pOffset /* OFFSET value. NULL means no offset */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 63 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 64 | Select *pNew; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 65 | Select standin; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 66 | sqlite3 *db = pParse->db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 67 | pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 68 | assert( !pOffset || pLimit ); /* Can't have OFFSET without LIMIT. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 69 |   if( pNew==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 70 | pNew = &standin; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 71 | memset(pNew, 0, sizeof(*pNew)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 72 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 73 |   if( pEList==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 74 | pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0,0,0), 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 75 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 76 | pNew->pEList = pEList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 77 | pNew->pSrc = pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 78 | pNew->pWhere = pWhere; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 79 | pNew->pGroupBy = pGroupBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 80 | pNew->pHaving = pHaving; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 81 | pNew->pOrderBy = pOrderBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 82 | pNew->selFlags = isDistinct ? SF_Distinct : 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 83 | pNew->op = TK_SELECT; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 84 | assert( pOffset==0 || pLimit!=0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 85 | pNew->pLimit = pLimit; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 86 | pNew->pOffset = pOffset; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 87 | pNew->addrOpenEphm[0] = -1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 88 | pNew->addrOpenEphm[1] = -1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 89 | pNew->addrOpenEphm[2] = -1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 90 |   if( db->mallocFailed ) {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 91 | clearSelect(db, pNew); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 92 | if( pNew!=&standin ) sqlite3DbFree(db, pNew); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 93 | pNew = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 94 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 95 | return pNew; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 96 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 97 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 98 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 99 | ** Delete the given Select structure and all of its substructures. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 100 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 101 | void sqlite3SelectDelete(sqlite3 *db, Select *p){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 102 |   if( p ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 103 | clearSelect(db, p); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 104 | sqlite3DbFree(db, p); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 105 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 106 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 107 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 108 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 109 | ** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 110 | ** type of join. Return an integer constant that expresses that type | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 111 | ** in terms of the following bit values: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 112 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 113 | ** JT_INNER | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 114 | ** JT_CROSS | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 115 | ** JT_OUTER | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 116 | ** JT_NATURAL | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 117 | ** JT_LEFT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 118 | ** JT_RIGHT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 119 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 120 | ** A full outer join is the combination of JT_LEFT and JT_RIGHT. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 121 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 122 | ** If an illegal or unsupported join type is seen, then still return | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 123 | ** a join type, but put an error in the pParse structure. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 124 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 125 | int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 126 | int jointype = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 127 | Token *apAll[3]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 128 | Token *p; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 129 |   static const struct {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 130 | const char zKeyword[8]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 131 | u8 nChar; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 132 | u8 code; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 133 |   } keywords[] = {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 134 |     { "natural", 7, JT_NATURAL },
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 135 |     { "left",    4, JT_LEFT|JT_OUTER },
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 136 |     { "right",   5, JT_RIGHT|JT_OUTER },
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 137 |     { "full",    4, JT_LEFT|JT_RIGHT|JT_OUTER },
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 138 |     { "outer",   5, JT_OUTER },
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 139 |     { "inner",   5, JT_INNER },
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 140 |     { "cross",   5, JT_INNER|JT_CROSS },
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 141 | }; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 142 | int i, j; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 143 | apAll[0] = pA; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 144 | apAll[1] = pB; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 145 | apAll[2] = pC; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 146 |   for(i=0; i<3 && apAll[i]; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 147 | p = apAll[i]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 148 |     for(j=0; j<sizeof(keywords)/sizeof(keywords[0]); j++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 149 | if( p->n==keywords[j].nChar | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 150 |           && sqlite3StrNICmp((char*)p->z, keywords[j].zKeyword, p->n)==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 151 | jointype |= keywords[j].code; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 152 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 153 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 154 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 155 |     if( j>=sizeof(keywords)/sizeof(keywords[0]) ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 156 | jointype |= JT_ERROR; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 157 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 158 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 159 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 160 | if( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 161 | (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) || | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 162 | (jointype & JT_ERROR)!=0 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 163 |   ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 164 | const char *zSp = " "; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 165 | assert( pB!=0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 166 |     if( pC==0 ){ zSp++; }
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 167 | sqlite3ErrorMsg(pParse, "unknown or unsupported join type: " | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 168 | "%T %T%s%T", pA, pB, zSp, pC); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 169 | jointype = JT_INNER; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 170 |   }else if( jointype & JT_RIGHT ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 171 | sqlite3ErrorMsg(pParse, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 172 | "RIGHT and FULL OUTER JOINs are not currently supported"); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 173 | jointype = JT_INNER; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 174 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 175 | return jointype; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 176 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 177 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 178 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 179 | ** Return the index of a column in a table. Return -1 if the column | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 180 | ** is not contained in the table. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 181 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 182 | static int columnIndex(Table *pTab, const char *zCol){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 183 | int i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 184 |   for(i=0; i<pTab->nCol; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 185 | if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 186 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 187 | return -1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 188 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 189 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 190 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 191 | ** Set the value of a token to a '\000'-terminated string. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 192 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 193 | static void setToken(Token *p, const char *z){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 194 | p->z = (u8*)z; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 195 | p->n = z ? strlen(z) : 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 196 | p->dyn = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 197 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 198 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 199 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 200 | ** Set the token to the double-quoted and escaped version of the string pointed | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 201 | ** to by z. For example; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 202 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 203 | **    {a"bc}  ->  {"a""bc"}
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 204 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 205 | static void setQuotedToken(Parse *pParse, Token *p, const char *z){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 206 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 207 | /* Check if the string appears to be quoted using "..." or `...` | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 208 | ** or [...] or '...' or if the string contains any " characters. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 209 | ** If it does, then record a version of the string with the special | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 210 | ** characters escaped. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 211 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 212 | const char *z2 = z; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 213 |   if( *z2!='[' && *z2!='`' && *z2!='\'' ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 214 |     while( *z2 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 215 | if( *z2=='"' ) break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 216 | z2++; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 217 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 218 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 219 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 220 |   if( *z2 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 221 | /* String contains " characters - copy and quote the string. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 222 | p->z = (u8 *)sqlite3MPrintf(pParse->db, "\"%w\"", z); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 223 |     if( p->z ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 224 | p->n = strlen((char *)p->z); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 225 | p->dyn = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 226 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 227 |   }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 228 | /* String contains no " characters - copy the pointer. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 229 | p->z = (u8*)z; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 230 | p->n = (z2 - z); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 231 | p->dyn = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 232 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 233 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 234 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 235 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 236 | ** Create an expression node for an identifier with the name of zName | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 237 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 238 | Expr *sqlite3CreateIdExpr(Parse *pParse, const char *zName){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 239 | Token dummy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 240 | setToken(&dummy, zName); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 241 | return sqlite3PExpr(pParse, TK_ID, 0, 0, &dummy); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 242 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 243 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 244 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 245 | ** Add a term to the WHERE expression in *ppExpr that requires the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 246 | ** zCol column to be equal in the two tables pTab1 and pTab2. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 247 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 248 | static void addWhereTerm( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 249 | Parse *pParse, /* Parsing context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 250 | const char *zCol, /* Name of the column */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 251 | const Table *pTab1, /* First table */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 252 | const char *zAlias1, /* Alias for first table. May be NULL */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 253 | const Table *pTab2, /* Second table */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 254 | const char *zAlias2, /* Alias for second table. May be NULL */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 255 | int iRightJoinTable, /* VDBE cursor for the right table */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 256 | Expr **ppExpr, /* Add the equality term to this expression */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 257 | int isOuterJoin /* True if dealing with an OUTER join */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 258 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 259 | Expr *pE1a, *pE1b, *pE1c; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 260 | Expr *pE2a, *pE2b, *pE2c; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 261 | Expr *pE; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 262 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 263 | pE1a = sqlite3CreateIdExpr(pParse, zCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 264 | pE2a = sqlite3CreateIdExpr(pParse, zCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 265 |   if( zAlias1==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 266 | zAlias1 = pTab1->zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 267 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 268 | pE1b = sqlite3CreateIdExpr(pParse, zAlias1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 269 |   if( zAlias2==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 270 | zAlias2 = pTab2->zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 271 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 272 | pE2b = sqlite3CreateIdExpr(pParse, zAlias2); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 273 | pE1c = sqlite3PExpr(pParse, TK_DOT, pE1b, pE1a, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 274 | pE2c = sqlite3PExpr(pParse, TK_DOT, pE2b, pE2a, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 275 | pE = sqlite3PExpr(pParse, TK_EQ, pE1c, pE2c, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 276 |   if( pE && isOuterJoin ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 277 | ExprSetProperty(pE, EP_FromJoin); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 278 | pE->iRightJoinTable = iRightJoinTable; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 279 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 280 | *ppExpr = sqlite3ExprAnd(pParse->db,*ppExpr, pE); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 281 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 282 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 283 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 284 | ** Set the EP_FromJoin property on all terms of the given expression. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 285 | ** And set the Expr.iRightJoinTable to iTable for every term in the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 286 | ** expression. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 287 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 288 | ** The EP_FromJoin property is used on terms of an expression to tell | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 289 | ** the LEFT OUTER JOIN processing logic that this term is part of the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 290 | ** join restriction specified in the ON or USING clause and not a part | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 291 | ** of the more general WHERE clause. These terms are moved over to the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 292 | ** WHERE clause during join processing but we need to remember that they | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 293 | ** originated in the ON or USING clause. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 294 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 295 | ** The Expr.iRightJoinTable tells the WHERE clause processing that the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 296 | ** expression depends on table iRightJoinTable even if that table is not | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 297 | ** explicitly mentioned in the expression. That information is needed | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 298 | ** for cases like this: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 299 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 300 | ** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 301 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 302 | ** The where clause needs to defer the handling of the t1.x=5 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 303 | ** term until after the t2 loop of the join. In that way, a | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 304 | ** NULL t2 row will be inserted whenever t1.x!=5. If we do not | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 305 | ** defer the handling of t1.x=5, it will be processed immediately | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 306 | ** after the t1 loop and rows with t1.x!=5 will never appear in | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 307 | ** the output, which is incorrect. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 308 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 309 | static void setJoinExpr(Expr *p, int iTable){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 310 |   while( p ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 311 | ExprSetProperty(p, EP_FromJoin); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 312 | p->iRightJoinTable = iTable; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 313 | setJoinExpr(p->pLeft, iTable); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 314 | p = p->pRight; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 315 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 316 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 317 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 318 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 319 | ** This routine processes the join information for a SELECT statement. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 320 | ** ON and USING clauses are converted into extra terms of the WHERE clause. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 321 | ** NATURAL joins also create extra WHERE clause terms. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 322 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 323 | ** The terms of a FROM clause are contained in the Select.pSrc structure. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 324 | ** The left most table is the first entry in Select.pSrc. The right-most | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 325 | ** table is the last entry. The join operator is held in the entry to | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 326 | ** the left. Thus entry 0 contains the join operator for the join between | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 327 | ** entries 0 and 1. Any ON or USING clauses associated with the join are | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 328 | ** also attached to the left entry. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 329 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 330 | ** This routine returns the number of errors encountered. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 331 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 332 | static int sqliteProcessJoin(Parse *pParse, Select *p){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 333 | SrcList *pSrc; /* All tables in the FROM clause */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 334 | int i, j; /* Loop counters */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 335 | struct SrcList_item *pLeft; /* Left table being joined */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 336 | struct SrcList_item *pRight; /* Right table being joined */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 337 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 338 | pSrc = p->pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 339 | pLeft = &pSrc->a[0]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 340 | pRight = &pLeft[1]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 341 |   for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 342 | Table *pLeftTab = pLeft->pTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 343 | Table *pRightTab = pRight->pTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 344 | int isOuter; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 345 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 346 | if( pLeftTab==0 || pRightTab==0 ) continue; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 347 | isOuter = (pRight->jointype & JT_OUTER)!=0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 348 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 349 | /* When the NATURAL keyword is present, add WHERE clause terms for | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 350 | ** every column that the two tables have in common. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 351 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 352 |     if( pRight->jointype & JT_NATURAL ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 353 |       if( pRight->pOn || pRight->pUsing ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 354 | sqlite3ErrorMsg(pParse, "a NATURAL join may not have " | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 355 | "an ON or USING clause", 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 356 | return 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 357 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 358 |       for(j=0; j<pLeftTab->nCol; j++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 359 | char *zName = pLeftTab->aCol[j].zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 360 |         if( columnIndex(pRightTab, zName)>=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 361 | addWhereTerm(pParse, zName, pLeftTab, pLeft->zAlias, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 362 | pRightTab, pRight->zAlias, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 363 | pRight->iCursor, &p->pWhere, isOuter); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 364 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 365 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 366 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 367 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 368 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 369 | /* Disallow both ON and USING clauses in the same join | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 370 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 371 |     if( pRight->pOn && pRight->pUsing ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 372 | sqlite3ErrorMsg(pParse, "cannot have both ON and USING " | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 373 | "clauses in the same join"); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 374 | return 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 375 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 376 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 377 | /* Add the ON clause to the end of the WHERE clause, connected by | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 378 | ** an AND operator. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 379 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 380 |     if( pRight->pOn ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 381 | if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 382 | p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 383 | pRight->pOn = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 384 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 385 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 386 | /* Create extra terms on the WHERE clause for each column named | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 387 | ** in the USING clause. Example: If the two tables to be joined are | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 388 | ** A and B and the USING clause names X, Y, and Z, then add this | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 389 | ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 390 | ** Report an error if any column mentioned in the USING clause is | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 391 | ** not contained in both tables to be joined. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 392 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 393 |     if( pRight->pUsing ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 394 | IdList *pList = pRight->pUsing; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 395 |       for(j=0; j<pList->nId; j++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 396 | char *zName = pList->a[j].zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 397 |         if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 398 | sqlite3ErrorMsg(pParse, "cannot join using column %s - column " | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 399 | "not present in both tables", zName); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 400 | return 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 401 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 402 | addWhereTerm(pParse, zName, pLeftTab, pLeft->zAlias, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 403 | pRightTab, pRight->zAlias, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 404 | pRight->iCursor, &p->pWhere, isOuter); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 405 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 406 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 407 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 408 | return 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 409 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 410 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 411 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 412 | ** Insert code into "v" that will push the record on the top of the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 413 | ** stack into the sorter. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 414 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 415 | static void pushOntoSorter( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 416 | Parse *pParse, /* Parser context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 417 | ExprList *pOrderBy, /* The ORDER BY clause */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 418 | Select *pSelect, /* The whole SELECT statement */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 419 | int regData /* Register holding data to be sorted */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 420 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 421 | Vdbe *v = pParse->pVdbe; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 422 | int nExpr = pOrderBy->nExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 423 | int regBase = sqlite3GetTempRange(pParse, nExpr+2); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 424 | int regRecord = sqlite3GetTempReg(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 425 | sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 426 | sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 427 | sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 428 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 429 | sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 430 | sqlite3ReleaseTempReg(pParse, regRecord); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 431 | sqlite3ReleaseTempRange(pParse, regBase, nExpr+2); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 432 |   if( pSelect->iLimit ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 433 | int addr1, addr2; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 434 | int iLimit; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 435 |     if( pSelect->iOffset ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 436 | iLimit = pSelect->iOffset+1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 437 |     }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 438 | iLimit = pSelect->iLimit; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 439 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 440 | addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 441 | sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 442 | addr2 = sqlite3VdbeAddOp0(v, OP_Goto); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 443 | sqlite3VdbeJumpHere(v, addr1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 444 | sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 445 | sqlite3VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 446 | sqlite3VdbeJumpHere(v, addr2); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 447 | pSelect->iLimit = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 448 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 449 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 450 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 451 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 452 | ** Add code to implement the OFFSET | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 453 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 454 | static void codeOffset( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 455 | Vdbe *v, /* Generate code into this VM */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 456 | Select *p, /* The SELECT statement being coded */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 457 | int iContinue /* Jump here to skip the current record */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 458 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 459 |   if( p->iOffset && iContinue!=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 460 | int addr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 461 | sqlite3VdbeAddOp2(v, OP_AddImm, p->iOffset, -1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 462 | addr = sqlite3VdbeAddOp1(v, OP_IfNeg, p->iOffset); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 463 | sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 464 | VdbeComment((v, "skip OFFSET records")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 465 | sqlite3VdbeJumpHere(v, addr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 466 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 467 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 468 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 469 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 470 | ** Add code that will check to make sure the N registers starting at iMem | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 471 | ** form a distinct entry. iTab is a sorting index that holds previously | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 472 | ** seen combinations of the N values. A new entry is made in iTab | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 473 | ** if the current N values are new. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 474 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 475 | ** A jump to addrRepeat is made and the N+1 values are popped from the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 476 | ** stack if the top N elements are not distinct. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 477 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 478 | static void codeDistinct( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 479 | Parse *pParse, /* Parsing and code generating context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 480 | int iTab, /* A sorting index used to test for distinctness */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 481 | int addrRepeat, /* Jump to here if not distinct */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 482 | int N, /* Number of elements */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 483 | int iMem /* First element */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 484 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 485 | Vdbe *v; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 486 | int r1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 487 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 488 | v = pParse->pVdbe; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 489 | r1 = sqlite3GetTempReg(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 490 | sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 491 | sqlite3VdbeAddOp3(v, OP_Found, iTab, addrRepeat, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 492 | sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 493 | sqlite3ReleaseTempReg(pParse, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 494 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 495 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 496 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 497 | ** Generate an error message when a SELECT is used within a subexpression | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 498 | ** (example: "a IN (SELECT * FROM table)") but it has more than 1 result | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 499 | ** column. We do this in a subroutine because the error occurs in multiple | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 500 | ** places. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 501 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 502 | static int checkForMultiColumnSelectError( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 503 | Parse *pParse, /* Parse context. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 504 | SelectDest *pDest, /* Destination of SELECT results */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 505 | int nExpr /* Number of result columns returned by SELECT */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 506 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 507 | int eDest = pDest->eDest; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 508 |   if( nExpr>1 && (eDest==SRT_Mem || eDest==SRT_Set) ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 509 | sqlite3ErrorMsg(pParse, "only a single result allowed for " | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 510 | "a SELECT that is part of an expression"); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 511 | return 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 512 |   }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 513 | return 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 514 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 515 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 516 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 517 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 518 | ** This routine generates the code for the inside of the inner loop | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 519 | ** of a SELECT. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 520 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 521 | ** If srcTab and nColumn are both zero, then the pEList expressions | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 522 | ** are evaluated in order to get the data for this row. If nColumn>0 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 523 | ** then data is pulled from srcTab and pEList is used only to get the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 524 | ** datatypes for each column. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 525 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 526 | static void selectInnerLoop( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 527 | Parse *pParse, /* The parser context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 528 | Select *p, /* The complete select statement being coded */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 529 | ExprList *pEList, /* List of values being extracted */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 530 | int srcTab, /* Pull data from this table */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 531 | int nColumn, /* Number of columns in the source table */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 532 | ExprList *pOrderBy, /* If not NULL, sort results using this key */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 533 | int distinct, /* If >=0, make sure results are distinct */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 534 | SelectDest *pDest, /* How to dispose of the results */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 535 | int iContinue, /* Jump here to continue with next row */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 536 | int iBreak /* Jump here to break out of the inner loop */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 537 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 538 | Vdbe *v = pParse->pVdbe; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 539 | int i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 540 | int hasDistinct; /* True if the DISTINCT keyword is present */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 541 | int regResult; /* Start of memory holding result set */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 542 | int eDest = pDest->eDest; /* How to dispose of results */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 543 | int iParm = pDest->iParm; /* First argument to disposal method */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 544 | int nResultCol; /* Number of result columns */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 545 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 546 | if( v==0 ) return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 547 | assert( pEList!=0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 548 | hasDistinct = distinct>=0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 549 |   if( pOrderBy==0 && !hasDistinct ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 550 | codeOffset(v, p, iContinue); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 551 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 552 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 553 | /* Pull the requested columns. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 554 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 555 |   if( nColumn>0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 556 | nResultCol = nColumn; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 557 |   }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 558 | nResultCol = pEList->nExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 559 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 560 |   if( pDest->iMem==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 561 | pDest->iMem = pParse->nMem+1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 562 | pDest->nMem = nResultCol; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 563 | pParse->nMem += nResultCol; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 564 |   }else if( pDest->nMem!=nResultCol ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 565 | /* This happens when two SELECTs of a compound SELECT have differing | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 566 | ** numbers of result columns. The error message will be generated by | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 567 | ** a higher-level routine. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 568 | return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 569 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 570 | regResult = pDest->iMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 571 |   if( nColumn>0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 572 |     for(i=0; i<nColumn; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 573 | sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 574 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 575 |   }else if( eDest!=SRT_Exists ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 576 | /* If the destination is an EXISTS(...) expression, the actual | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 577 | ** values returned by the SELECT are not required. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 578 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 579 | sqlite3ExprCodeExprList(pParse, pEList, regResult, eDest==SRT_Output); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 580 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 581 | nColumn = nResultCol; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 582 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 583 | /* If the DISTINCT keyword was present on the SELECT statement | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 584 | ** and this row has been seen before, then do not make this row | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 585 | ** part of the result. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 586 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 587 |   if( hasDistinct ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 588 | assert( pEList!=0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 589 | assert( pEList->nExpr==nColumn ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 590 | codeDistinct(pParse, distinct, iContinue, nColumn, regResult); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 591 |     if( pOrderBy==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 592 | codeOffset(v, p, iContinue); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 593 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 594 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 595 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 596 |   if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 597 | return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 598 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 599 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 600 |   switch( eDest ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 601 | /* In this mode, write each query result to the key of the temporary | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 602 | ** table iParm. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 603 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 604 | #ifndef SQLITE_OMIT_COMPOUND_SELECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 605 |     case SRT_Union: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 606 | int r1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 607 | r1 = sqlite3GetTempReg(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 608 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 609 | sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 610 | sqlite3ReleaseTempReg(pParse, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 611 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 612 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 613 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 614 | /* Construct a record from the query result, but instead of | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 615 | ** saving that record, use it as a key to delete elements from | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 616 | ** the temporary table iParm. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 617 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 618 |     case SRT_Except: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 619 | sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nColumn); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 620 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 621 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 622 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 623 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 624 | /* Store the result as data using a unique key. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 625 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 626 | case SRT_Table: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 627 |     case SRT_EphemTab: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 628 | int r1 = sqlite3GetTempReg(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 629 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 630 |       if( pOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 631 | pushOntoSorter(pParse, pOrderBy, p, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 632 |       }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 633 | int r2 = sqlite3GetTempReg(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 634 | sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 635 | sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 636 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 637 | sqlite3ReleaseTempReg(pParse, r2); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 638 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 639 | sqlite3ReleaseTempReg(pParse, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 640 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 641 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 642 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 643 | #ifndef SQLITE_OMIT_SUBQUERY | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 644 | /* If we are creating a set for an "expr IN (SELECT ...)" construct, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 645 | ** then there should be a single item on the stack. Write this | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 646 | ** item into the set table with bogus data. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 647 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 648 |     case SRT_Set: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 649 | assert( nColumn==1 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 650 | p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 651 |       if( pOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 652 | /* At first glance you would think we could optimize out the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 653 | ** ORDER BY in this case since the order of entries in the set | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 654 | ** does not matter. But there might be a LIMIT clause, in which | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 655 | ** case the order does matter */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 656 | pushOntoSorter(pParse, pOrderBy, p, regResult); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 657 |       }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 658 | int r1 = sqlite3GetTempReg(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 659 | sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 660 | sqlite3ExprCacheAffinityChange(pParse, regResult, 1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 661 | sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 662 | sqlite3ReleaseTempReg(pParse, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 663 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 664 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 665 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 666 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 667 | /* If any row exist in the result set, record that fact and abort. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 668 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 669 |     case SRT_Exists: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 670 | sqlite3VdbeAddOp2(v, OP_Integer, 1, iParm); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 671 | /* The LIMIT clause will terminate the loop for us */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 672 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 673 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 674 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 675 | /* If this is a scalar select that is part of an expression, then | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 676 | ** store the results in the appropriate memory cell and break out | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 677 | ** of the scan loop. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 678 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 679 |     case SRT_Mem: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 680 | assert( nColumn==1 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 681 |       if( pOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 682 | pushOntoSorter(pParse, pOrderBy, p, regResult); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 683 |       }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 684 | sqlite3ExprCodeMove(pParse, regResult, iParm, 1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 685 | /* The LIMIT clause will jump out of the loop for us */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 686 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 687 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 688 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 689 | #endif /* #ifndef SQLITE_OMIT_SUBQUERY */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 690 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 691 | /* Send the data to the callback function or to a subroutine. In the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 692 | ** case of a subroutine, the subroutine itself is responsible for | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 693 | ** popping the data from the stack. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 694 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 695 | case SRT_Coroutine: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 696 |     case SRT_Output: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 697 |       if( pOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 698 | int r1 = sqlite3GetTempReg(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 699 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 700 | pushOntoSorter(pParse, pOrderBy, p, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 701 | sqlite3ReleaseTempReg(pParse, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 702 |       }else if( eDest==SRT_Coroutine ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 703 | sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 704 |       }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 705 | sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 706 | sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 707 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 708 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 709 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 710 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 711 | #if !defined(SQLITE_OMIT_TRIGGER) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 712 | /* Discard the results. This is used for SELECT statements inside | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 713 | ** the body of a TRIGGER. The purpose of such selects is to call | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 714 | ** user-defined functions that have side effects. We do not care | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 715 | ** about the actual results of the select. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 716 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 717 |     default: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 718 | assert( eDest==SRT_Discard ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 719 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 720 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 721 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 722 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 723 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 724 | /* Jump to the end of the loop if the LIMIT is reached. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 725 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 726 |   if( p->iLimit ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 727 | assert( pOrderBy==0 ); /* If there is an ORDER BY, the call to | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 728 | ** pushOntoSorter() would have cleared p->iLimit */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 729 | sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 730 | sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 731 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 732 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 733 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 734 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 735 | ** Given an expression list, generate a KeyInfo structure that records | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 736 | ** the collating sequence for each expression in that expression list. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 737 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 738 | ** If the ExprList is an ORDER BY or GROUP BY clause then the resulting | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 739 | ** KeyInfo structure is appropriate for initializing a virtual index to | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 740 | ** implement that clause. If the ExprList is the result set of a SELECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 741 | ** then the KeyInfo structure is appropriate for initializing a virtual | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 742 | ** index to implement a DISTINCT test. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 743 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 744 | ** Space to hold the KeyInfo structure is obtain from malloc. The calling | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 745 | ** function is responsible for seeing that this structure is eventually | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 746 | ** freed. Add the KeyInfo structure to the P4 field of an opcode using | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 747 | ** P4_KEYINFO_HANDOFF is the usual way of dealing with this. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 748 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 749 | static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 750 | sqlite3 *db = pParse->db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 751 | int nExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 752 | KeyInfo *pInfo; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 753 | struct ExprList_item *pItem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 754 | int i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 755 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 756 | nExpr = pList->nExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 757 | pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 758 |   if( pInfo ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 759 | pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 760 | pInfo->nField = nExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 761 | pInfo->enc = ENC(db); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 762 |     for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 763 | CollSeq *pColl; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 764 | pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 765 |       if( !pColl ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 766 | pColl = db->pDfltColl; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 767 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 768 | pInfo->aColl[i] = pColl; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 769 | pInfo->aSortOrder[i] = pItem->sortOrder; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 770 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 771 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 772 | return pInfo; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 773 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 774 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 775 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 776 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 777 | ** If the inner loop was generated using a non-null pOrderBy argument, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 778 | ** then the results were placed in a sorter. After the loop is terminated | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 779 | ** we need to run the sorter and output the results. The following | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 780 | ** routine generates the code needed to do that. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 781 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 782 | static void generateSortTail( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 783 | Parse *pParse, /* Parsing context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 784 | Select *p, /* The SELECT statement */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 785 | Vdbe *v, /* Generate code into this VDBE */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 786 | int nColumn, /* Number of columns of data */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 787 | SelectDest *pDest /* Write the sorted results here */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 788 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 789 | int brk = sqlite3VdbeMakeLabel(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 790 | int cont = sqlite3VdbeMakeLabel(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 791 | int addr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 792 | int iTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 793 | int pseudoTab = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 794 | ExprList *pOrderBy = p->pOrderBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 795 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 796 | int eDest = pDest->eDest; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 797 | int iParm = pDest->iParm; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 798 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 799 | int regRow; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 800 | int regRowid; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 801 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 802 | iTab = pOrderBy->iECursor; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 803 |   if( eDest==SRT_Output || eDest==SRT_Coroutine ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 804 | pseudoTab = pParse->nTab++; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 805 | sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, nColumn); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 806 | sqlite3VdbeAddOp2(v, OP_OpenPseudo, pseudoTab, eDest==SRT_Output); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 807 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 808 | addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, brk); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 809 | codeOffset(v, p, cont); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 810 | regRow = sqlite3GetTempReg(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 811 | regRowid = sqlite3GetTempReg(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 812 | sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr + 1, regRow); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 813 |   switch( eDest ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 814 | case SRT_Table: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 815 |     case SRT_EphemTab: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 816 | sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 817 | sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 818 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 819 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 820 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 821 | #ifndef SQLITE_OMIT_SUBQUERY | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 822 |     case SRT_Set: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 823 | assert( nColumn==1 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 824 | sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 825 | sqlite3ExprCacheAffinityChange(pParse, regRow, 1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 826 | sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 827 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 828 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 829 |     case SRT_Mem: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 830 | assert( nColumn==1 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 831 | sqlite3ExprCodeMove(pParse, regRow, iParm, 1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 832 | /* The LIMIT clause will terminate the loop for us */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 833 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 834 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 835 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 836 | case SRT_Output: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 837 |     case SRT_Coroutine: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 838 | int i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 839 | sqlite3VdbeAddOp2(v, OP_Integer, 1, regRowid); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 840 | sqlite3VdbeAddOp3(v, OP_Insert, pseudoTab, regRow, regRowid); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 841 |       for(i=0; i<nColumn; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 842 | assert( regRow!=pDest->iMem+i ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 843 | sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 844 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 845 |       if( eDest==SRT_Output ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 846 | sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 847 | sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 848 |       }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 849 | sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 850 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 851 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 852 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 853 |     default: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 854 | /* Do nothing */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 855 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 856 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 857 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 858 | sqlite3ReleaseTempReg(pParse, regRow); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 859 | sqlite3ReleaseTempReg(pParse, regRowid); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 860 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 861 | /* LIMIT has been implemented by the pushOntoSorter() routine. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 862 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 863 | assert( p->iLimit==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 864 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 865 | /* The bottom of the loop | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 866 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 867 | sqlite3VdbeResolveLabel(v, cont); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 868 | sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 869 | sqlite3VdbeResolveLabel(v, brk); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 870 |   if( eDest==SRT_Output || eDest==SRT_Coroutine ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 871 | sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 872 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 873 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 874 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 875 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 876 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 877 | ** Return a pointer to a string containing the 'declaration type' of the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 878 | ** expression pExpr. The string may be treated as static by the caller. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 879 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 880 | ** The declaration type is the exact datatype definition extracted from the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 881 | ** original CREATE TABLE statement if the expression is a column. The | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 882 | ** declaration type for a ROWID field is INTEGER. Exactly when an expression | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 883 | ** is considered a column can be complex in the presence of subqueries. The | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 884 | ** result-set expression in all of the following SELECT statements is | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 885 | ** considered a column by this function. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 886 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 887 | ** SELECT col FROM tbl; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 888 | ** SELECT (SELECT col FROM tbl; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 889 | ** SELECT (SELECT col FROM tbl); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 890 | ** SELECT abc FROM (SELECT col AS abc FROM tbl); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 891 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 892 | ** The declaration type for any expression other than a column is NULL. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 893 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 894 | static const char *columnType( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 895 | NameContext *pNC, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 896 | Expr *pExpr, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 897 | const char **pzOriginDb, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 898 | const char **pzOriginTab, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 899 | const char **pzOriginCol | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 900 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 901 | char const *zType = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 902 | char const *zOriginDb = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 903 | char const *zOriginTab = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 904 | char const *zOriginCol = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 905 | int j; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 906 | if( pExpr==0 || pNC->pSrcList==0 ) return 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 907 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 908 |   switch( pExpr->op ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 909 | case TK_AGG_COLUMN: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 910 |     case TK_COLUMN: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 911 | /* The expression is a column. Locate the table the column is being | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 912 | ** extracted from in NameContext.pSrcList. This table may be real | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 913 | ** database table or a subquery. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 914 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 915 | Table *pTab = 0; /* Table structure column is extracted from */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 916 | Select *pS = 0; /* Select the column is extracted from */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 917 | int iCol = pExpr->iColumn; /* Index of column in pTab */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 918 |       while( pNC && !pTab ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 919 | SrcList *pTabList = pNC->pSrcList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 920 | for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 921 |         if( j<pTabList->nSrc ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 922 | pTab = pTabList->a[j].pTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 923 | pS = pTabList->a[j].pSelect; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 924 |         }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 925 | pNC = pNC->pNext; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 926 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 927 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 928 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 929 |       if( pTab==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 930 | /* FIX ME: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 931 | ** This can occurs if you have something like "SELECT new.x;" inside | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 932 | ** a trigger. In other words, if you reference the special "new" | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 933 | ** table in the result set of a select. We do not have a good way | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 934 | ** to find the actual table type, so call it "TEXT". This is really | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 935 | ** something of a bug, but I do not know how to fix it. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 936 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 937 | ** This code does not produce the correct answer - it just prevents | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 938 | ** a segfault. See ticket #1229. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 939 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 940 | zType = "TEXT"; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 941 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 942 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 943 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 944 | assert( pTab ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 945 |       if( pS ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 946 | /* The "table" is actually a sub-select or a view in the FROM clause | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 947 | ** of the SELECT statement. Return the declaration type and origin | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 948 | ** data for the result-set column of the sub-select. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 949 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 950 |         if( iCol>=0 && iCol<pS->pEList->nExpr ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 951 | /* If iCol is less than zero, then the expression requests the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 952 | ** rowid of the sub-select or view. This expression is legal (see | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 953 | ** test case misc2.2.2) - it always evaluates to NULL. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 954 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 955 | NameContext sNC; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 956 | Expr *p = pS->pEList->a[iCol].pExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 957 | sNC.pSrcList = pS->pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 958 | sNC.pNext = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 959 | sNC.pParse = pNC->pParse; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 960 | zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 961 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 962 |       }else if( pTab->pSchema ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 963 | /* A real table */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 964 | assert( !pS ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 965 | if( iCol<0 ) iCol = pTab->iPKey; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 966 | assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 967 |         if( iCol<0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 968 | zType = "INTEGER"; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 969 | zOriginCol = "rowid"; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 970 |         }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 971 | zType = pTab->aCol[iCol].zType; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 972 | zOriginCol = pTab->aCol[iCol].zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 973 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 974 | zOriginTab = pTab->zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 975 |         if( pNC->pParse ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 976 | int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 977 | zOriginDb = pNC->pParse->db->aDb[iDb].zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 978 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 979 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 980 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 981 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 982 | #ifndef SQLITE_OMIT_SUBQUERY | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 983 |     case TK_SELECT: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 984 | /* The expression is a sub-select. Return the declaration type and | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 985 | ** origin info for the single column in the result set of the SELECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 986 | ** statement. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 987 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 988 | NameContext sNC; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 989 | Select *pS = pExpr->pSelect; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 990 | Expr *p = pS->pEList->a[0].pExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 991 | sNC.pSrcList = pS->pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 992 | sNC.pNext = pNC; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 993 | sNC.pParse = pNC->pParse; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 994 | zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 995 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 996 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 997 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 998 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 999 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1000 |   if( pzOriginDb ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1001 | assert( pzOriginTab && pzOriginCol ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1002 | *pzOriginDb = zOriginDb; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1003 | *pzOriginTab = zOriginTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1004 | *pzOriginCol = zOriginCol; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1005 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1006 | return zType; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1007 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1008 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1009 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1010 | ** Generate code that will tell the VDBE the declaration types of columns | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1011 | ** in the result set. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1012 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1013 | static void generateColumnTypes( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1014 | Parse *pParse, /* Parser context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1015 | SrcList *pTabList, /* List of tables */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1016 | ExprList *pEList /* Expressions defining the result set */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1017 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1018 | #ifndef SQLITE_OMIT_DECLTYPE | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1019 | Vdbe *v = pParse->pVdbe; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1020 | int i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1021 | NameContext sNC; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1022 | sNC.pSrcList = pTabList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1023 | sNC.pParse = pParse; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1024 |   for(i=0; i<pEList->nExpr; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1025 | Expr *p = pEList->a[i].pExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1026 | const char *zType; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1027 | #ifdef SQLITE_ENABLE_COLUMN_METADATA | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1028 | const char *zOrigDb = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1029 | const char *zOrigTab = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1030 | const char *zOrigCol = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1031 | zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1032 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1033 | /* The vdbe must make its own copy of the column-type and other | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1034 | ** column specific strings, in case the schema is reset before this | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1035 | ** virtual machine is deleted. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1036 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1037 | sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, P4_TRANSIENT); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1038 | sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, P4_TRANSIENT); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1039 | sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, P4_TRANSIENT); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1040 | #else | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1041 | zType = columnType(&sNC, p, 0, 0, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1042 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1043 | sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, P4_TRANSIENT); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1044 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1045 | #endif /* SQLITE_OMIT_DECLTYPE */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1046 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1047 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1048 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1049 | ** Generate code that will tell the VDBE the names of columns | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1050 | ** in the result set. This information is used to provide the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1051 | ** azCol[] values in the callback. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1052 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1053 | static void generateColumnNames( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1054 | Parse *pParse, /* Parser context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1055 | SrcList *pTabList, /* List of tables */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1056 | ExprList *pEList /* Expressions defining the result set */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1057 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1058 | Vdbe *v = pParse->pVdbe; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1059 | int i, j; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1060 | sqlite3 *db = pParse->db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1061 | int fullNames, shortNames; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1062 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1063 | #ifndef SQLITE_OMIT_EXPLAIN | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1064 | /* If this is an EXPLAIN, skip this step */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1065 |   if( pParse->explain ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1066 | return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1067 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1068 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1069 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1070 | assert( v!=0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1071 | if( pParse->colNamesSet || v==0 || db->mallocFailed ) return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1072 | pParse->colNamesSet = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1073 | fullNames = (db->flags & SQLITE_FullColNames)!=0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1074 | shortNames = (db->flags & SQLITE_ShortColNames)!=0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1075 | sqlite3VdbeSetNumCols(v, pEList->nExpr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1076 |   for(i=0; i<pEList->nExpr; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1077 | Expr *p; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1078 | p = pEList->a[i].pExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1079 | if( p==0 ) continue; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1080 |     if( pEList->a[i].zName ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1081 | char *zName = pEList->a[i].zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1082 | sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, strlen(zName)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1083 |     }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) && pTabList ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1084 | Table *pTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1085 | char *zCol; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1086 | int iCol = p->iColumn; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1087 |       for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1088 | assert( j<pTabList->nSrc ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1089 | pTab = pTabList->a[j].pTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1090 | if( iCol<0 ) iCol = pTab->iPKey; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1091 | assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1092 |       if( iCol<0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1093 | zCol = "rowid"; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1094 |       }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1095 | zCol = pTab->aCol[iCol].zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1096 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1097 |       if( !shortNames && !fullNames ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1098 | sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1099 |       }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1100 | char *zName = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1101 | char *zTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1102 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1103 | zTab = pTabList->a[j].zAlias; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1104 | if( fullNames || zTab==0 ) zTab = pTab->zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1105 | zName = sqlite3MPrintf(db, "%s.%s", zTab, zCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1106 | sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, P4_DYNAMIC); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1107 |       }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1108 | sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, strlen(zCol)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1109 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1110 |     }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1111 | sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1112 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1113 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1114 | generateColumnTypes(pParse, pTabList, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1115 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1116 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1117 | #ifndef SQLITE_OMIT_COMPOUND_SELECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1118 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1119 | ** Name of the connection operator, used for error messages. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1120 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1121 | static const char *selectOpName(int id){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1122 | char *z; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1123 |   switch( id ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1124 | case TK_ALL: z = "UNION ALL"; break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1125 | case TK_INTERSECT: z = "INTERSECT"; break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1126 | case TK_EXCEPT: z = "EXCEPT"; break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1127 | default: z = "UNION"; break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1128 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1129 | return z; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1130 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1131 | #endif /* SQLITE_OMIT_COMPOUND_SELECT */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1132 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1133 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1134 | ** Given a an expression list (which is really the list of expressions | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1135 | ** that form the result set of a SELECT statement) compute appropriate | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1136 | ** column names for a table that would hold the expression list. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1137 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1138 | ** All column names will be unique. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1139 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1140 | ** Only the column names are computed. Column.zType, Column.zColl, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1141 | ** and other fields of Column are zeroed. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1142 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1143 | ** Return SQLITE_OK on success. If a memory allocation error occurs, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1144 | ** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1145 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1146 | static int selectColumnsFromExprList( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1147 | Parse *pParse, /* Parsing context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1148 | ExprList *pEList, /* Expr list from which to derive column names */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1149 | int *pnCol, /* Write the number of columns here */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1150 | Column **paCol /* Write the new column list here */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1151 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1152 | sqlite3 *db = pParse->db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1153 | int i, j, cnt; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1154 | Column *aCol, *pCol; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1155 | int nCol; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1156 | Expr *p; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1157 | char *zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1158 | int nName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1159 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1160 | *pnCol = nCol = pEList->nExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1161 | aCol = *paCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1162 | if( aCol==0 ) return SQLITE_NOMEM; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1163 |   for(i=0, pCol=aCol; i<nCol; i++, pCol++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1164 | /* Get an appropriate name for the column | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1165 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1166 | p = pEList->a[i].pExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1167 | assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1168 |     if( (zName = pEList->a[i].zName)!=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1169 | /* If the column contains an "AS <name>" phrase, use <name> as the name */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1170 | zName = sqlite3DbStrDup(db, zName); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1171 |     }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1172 | Expr *pCol = p; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1173 | Table *pTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1174 | while( pCol->op==TK_DOT ) pCol = pCol->pRight; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1175 |       if( pCol->op==TK_COLUMN && (pTab = pCol->pTab)!=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1176 | /* For columns use the column name name */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1177 | int iCol = pCol->iColumn; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1178 | if( iCol<0 ) iCol = pTab->iPKey; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1179 | zName = sqlite3MPrintf(db, "%s", | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1180 | iCol>=0 ? pTab->aCol[iCol].zName : "rowid"); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1181 |       }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1182 | /* Use the original text of the column expression as its name */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1183 | zName = sqlite3MPrintf(db, "%T", &pCol->span); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1184 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1185 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1186 |     if( db->mallocFailed ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1187 | sqlite3DbFree(db, zName); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1188 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1189 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1190 | sqlite3Dequote(zName); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1191 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1192 | /* Make sure the column name is unique. If the name is not unique, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1193 | ** append a integer to the name so that it becomes unique. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1194 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1195 | nName = strlen(zName); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1196 |     for(j=cnt=0; j<i; j++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1197 |       if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1198 | char *zNewName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1199 | zName[nName] = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1200 | zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1201 | sqlite3DbFree(db, zName); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1202 | zName = zNewName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1203 | j = -1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1204 | if( zName==0 ) break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1205 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1206 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1207 | pCol->zName = zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1208 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1209 |   if( db->mallocFailed ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1210 | int j; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1211 |     for(j=0; j<i; j++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1212 | sqlite3DbFree(db, aCol[j].zName); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1213 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1214 | sqlite3DbFree(db, aCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1215 | *paCol = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1216 | *pnCol = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1217 | return SQLITE_NOMEM; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1218 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1219 | return SQLITE_OK; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1220 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1221 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1222 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1223 | ** Add type and collation information to a column list based on | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1224 | ** a SELECT statement. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1225 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1226 | ** The column list presumably came from selectColumnNamesFromExprList(). | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1227 | ** The column list has only names, not types or collations. This | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1228 | ** routine goes through and adds the types and collations. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1229 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1230 | ** This routine requires that all indentifiers in the SELECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1231 | ** statement be resolved. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1232 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1233 | static void selectAddColumnTypeAndCollation( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1234 | Parse *pParse, /* Parsing contexts */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1235 | int nCol, /* Number of columns */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1236 | Column *aCol, /* List of columns */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1237 | Select *pSelect /* SELECT used to determine types and collations */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1238 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1239 | sqlite3 *db = pParse->db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1240 | NameContext sNC; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1241 | Column *pCol; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1242 | CollSeq *pColl; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1243 | int i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1244 | Expr *p; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1245 | struct ExprList_item *a; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1246 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1247 | assert( pSelect!=0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1248 | assert( (pSelect->selFlags & SF_Resolved)!=0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1249 | assert( nCol==pSelect->pEList->nExpr || db->mallocFailed ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1250 | if( db->mallocFailed ) return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1251 | memset(&sNC, 0, sizeof(sNC)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1252 | sNC.pSrcList = pSelect->pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1253 | a = pSelect->pEList->a; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1254 |   for(i=0, pCol=aCol; i<nCol; i++, pCol++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1255 | p = a[i].pExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1256 | pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1257 | pCol->affinity = sqlite3ExprAffinity(p); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1258 | pColl = sqlite3ExprCollSeq(pParse, p); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1259 |     if( pColl ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1260 | pCol->zColl = sqlite3DbStrDup(db, pColl->zName); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1261 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1262 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1263 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1264 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1265 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1266 | ** Given a SELECT statement, generate a Table structure that describes | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1267 | ** the result set of that SELECT. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1268 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1269 | Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1270 | Table *pTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1271 | sqlite3 *db = pParse->db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1272 | int savedFlags; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1273 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1274 | savedFlags = db->flags; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1275 | db->flags &= ~SQLITE_FullColNames; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1276 | db->flags |= SQLITE_ShortColNames; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1277 | sqlite3SelectPrep(pParse, pSelect, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1278 | if( pParse->nErr ) return 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1279 | while( pSelect->pPrior ) pSelect = pSelect->pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1280 | db->flags = savedFlags; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1281 | pTab = sqlite3DbMallocZero(db, sizeof(Table) ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1282 |   if( pTab==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1283 | return 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1284 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1285 | pTab->db = db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1286 | pTab->nRef = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1287 | pTab->zName = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1288 | selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1289 | selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1290 | pTab->iPKey = -1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1291 |   if( db->mallocFailed ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1292 | sqlite3DeleteTable(pTab); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1293 | return 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1294 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1295 | return pTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1296 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1297 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1298 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1299 | ** Get a VDBE for the given parser context. Create a new one if necessary. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1300 | ** If an error occurs, return NULL and leave a message in pParse. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1301 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1302 | Vdbe *sqlite3GetVdbe(Parse *pParse){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1303 | Vdbe *v = pParse->pVdbe; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1304 |   if( v==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1305 | v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1306 | #ifndef SQLITE_OMIT_TRACE | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1307 |     if( v ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1308 | sqlite3VdbeAddOp0(v, OP_Trace); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1309 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1310 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1311 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1312 | return v; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1313 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1314 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1315 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1316 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1317 | ** Compute the iLimit and iOffset fields of the SELECT based on the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1318 | ** pLimit and pOffset expressions. pLimit and pOffset hold the expressions | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1319 | ** that appear in the original SQL statement after the LIMIT and OFFSET | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1320 | ** keywords. Or NULL if those keywords are omitted. iLimit and iOffset | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1321 | ** are the integer memory register numbers for counters used to compute | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1322 | ** the limit and offset. If there is no limit and/or offset, then | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1323 | ** iLimit and iOffset are negative. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1324 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1325 | ** This routine changes the values of iLimit and iOffset only if | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1326 | ** a limit or offset is defined by pLimit and pOffset. iLimit and | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1327 | ** iOffset should have been preset to appropriate default values | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1328 | ** (usually but not always -1) prior to calling this routine. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1329 | ** Only if pLimit!=0 or pOffset!=0 do the limit registers get | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1330 | ** redefined. The UNION ALL operator uses this property to force | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1331 | ** the reuse of the same limit and offset registers across multiple | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1332 | ** SELECT statements. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1333 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1334 | static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1335 | Vdbe *v = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1336 | int iLimit = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1337 | int iOffset; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1338 | int addr1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1339 | if( p->iLimit ) return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1340 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1341 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1342 | ** "LIMIT -1" always shows all rows. There is some | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1343 | ** contraversy about what the correct behavior should be. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1344 | ** The current implementation interprets "LIMIT 0" to mean | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1345 | ** no rows. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1346 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1347 |   if( p->pLimit ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1348 | p->iLimit = iLimit = ++pParse->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1349 | v = sqlite3GetVdbe(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1350 | if( v==0 ) return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1351 | sqlite3ExprCode(pParse, p->pLimit, iLimit); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1352 | sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1353 | VdbeComment((v, "LIMIT counter")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1354 | sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1355 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1356 |   if( p->pOffset ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1357 | p->iOffset = iOffset = ++pParse->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1358 |     if( p->pLimit ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1359 | pParse->nMem++; /* Allocate an extra register for limit+offset */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1360 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1361 | v = sqlite3GetVdbe(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1362 | if( v==0 ) return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1363 | sqlite3ExprCode(pParse, p->pOffset, iOffset); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1364 | sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1365 | VdbeComment((v, "OFFSET counter")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1366 | addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1367 | sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1368 | sqlite3VdbeJumpHere(v, addr1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1369 |     if( p->pLimit ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1370 | sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1371 | VdbeComment((v, "LIMIT+OFFSET")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1372 | addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1373 | sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1374 | sqlite3VdbeJumpHere(v, addr1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1375 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1376 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1377 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1378 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1379 | #ifndef SQLITE_OMIT_COMPOUND_SELECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1380 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1381 | ** Return the appropriate collating sequence for the iCol-th column of | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1382 | ** the result set for the compound-select statement "p". Return NULL if | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1383 | ** the column has no default collating sequence. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1384 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1385 | ** The collating sequence for the compound select is taken from the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1386 | ** left-most term of the select that has a collating sequence. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1387 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1388 | static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1389 | CollSeq *pRet; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1390 |   if( p->pPrior ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1391 | pRet = multiSelectCollSeq(pParse, p->pPrior, iCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1392 |   }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1393 | pRet = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1394 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1395 |   if( pRet==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1396 | pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1397 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1398 | return pRet; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1399 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1400 | #endif /* SQLITE_OMIT_COMPOUND_SELECT */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1401 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1402 | /* Forward reference */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1403 | static int multiSelectOrderBy( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1404 | Parse *pParse, /* Parsing context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1405 | Select *p, /* The right-most of SELECTs to be coded */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1406 | SelectDest *pDest /* What to do with query results */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1407 | ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1408 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1409 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1410 | #ifndef SQLITE_OMIT_COMPOUND_SELECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1411 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1412 | ** This routine is called to process a compound query form from | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1413 | ** two or more separate queries using UNION, UNION ALL, EXCEPT, or | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1414 | ** INTERSECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1415 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1416 | ** "p" points to the right-most of the two queries. the query on the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1417 | ** left is p->pPrior. The left query could also be a compound query | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1418 | ** in which case this routine will be called recursively. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1419 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1420 | ** The results of the total query are to be written into a destination | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1421 | ** of type eDest with parameter iParm. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1422 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1423 | ** Example 1: Consider a three-way compound SQL statement. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1424 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1425 | ** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1426 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1427 | ** This statement is parsed up as follows: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1428 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1429 | ** SELECT c FROM t3 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1430 | ** | | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1431 | ** `-----> SELECT b FROM t2 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1432 | ** | | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1433 | ** `------> SELECT a FROM t1 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1434 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1435 | ** The arrows in the diagram above represent the Select.pPrior pointer. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1436 | ** So if this routine is called with p equal to the t3 query, then | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1437 | ** pPrior will be the t2 query. p->op will be TK_UNION in this case. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1438 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1439 | ** Notice that because of the way SQLite parses compound SELECTs, the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1440 | ** individual selects always group from left to right. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1441 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1442 | static int multiSelect( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1443 | Parse *pParse, /* Parsing context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1444 | Select *p, /* The right-most of SELECTs to be coded */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1445 | SelectDest *pDest /* What to do with query results */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1446 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1447 | int rc = SQLITE_OK; /* Success code from a subroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1448 | Select *pPrior; /* Another SELECT immediately to our left */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1449 | Vdbe *v; /* Generate code to this VDBE */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1450 | SelectDest dest; /* Alternative data destination */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1451 | Select *pDelete = 0; /* Chain of simple selects to delete */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1452 | sqlite3 *db; /* Database connection */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1453 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1454 | /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1455 | ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1456 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1457 | assert( p && p->pPrior ); /* Calling function guarantees this much */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1458 | db = pParse->db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1459 | pPrior = p->pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1460 | assert( pPrior->pRightmost!=pPrior ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1461 | assert( pPrior->pRightmost==p->pRightmost ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1462 | dest = *pDest; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1463 |   if( pPrior->pOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1464 | sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before", | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1465 | selectOpName(p->op)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1466 | rc = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1467 | goto multi_select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1468 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1469 |   if( pPrior->pLimit ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1470 | sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before", | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1471 | selectOpName(p->op)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1472 | rc = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1473 | goto multi_select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1474 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1475 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1476 | v = sqlite3GetVdbe(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1477 | assert( v!=0 ); /* The VDBE already created by calling function */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1478 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1479 | /* Create the destination temporary table if necessary | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1480 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1481 |   if( dest.eDest==SRT_EphemTab ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1482 | assert( p->pEList ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1483 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1484 | dest.eDest = SRT_Table; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1485 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1486 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1487 | /* Make sure all SELECTs in the statement have the same number of elements | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1488 | ** in their result sets. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1489 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1490 | assert( p->pEList && pPrior->pEList ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1491 |   if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1492 | sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1493 | " do not have the same number of result columns", selectOpName(p->op)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1494 | rc = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1495 | goto multi_select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1496 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1497 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1498 | /* Compound SELECTs that have an ORDER BY clause are handled separately. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1499 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1500 |   if( p->pOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1501 | return multiSelectOrderBy(pParse, p, pDest); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1502 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1503 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1504 | /* Generate code for the left and right SELECT statements. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1505 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1506 |   switch( p->op ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1507 |     case TK_ALL: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1508 | int addr = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1509 | assert( !pPrior->pLimit ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1510 | pPrior->pLimit = p->pLimit; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1511 | pPrior->pOffset = p->pOffset; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1512 | rc = sqlite3Select(pParse, pPrior, &dest); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1513 | p->pLimit = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1514 | p->pOffset = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1515 |       if( rc ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1516 | goto multi_select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1517 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1518 | p->pPrior = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1519 | p->iLimit = pPrior->iLimit; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1520 | p->iOffset = pPrior->iOffset; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1521 |       if( p->iLimit ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1522 | addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1523 | VdbeComment((v, "Jump ahead if LIMIT reached")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1524 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1525 | rc = sqlite3Select(pParse, p, &dest); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1526 | pDelete = p->pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1527 | p->pPrior = pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1528 |       if( rc ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1529 | goto multi_select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1530 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1531 |       if( addr ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1532 | sqlite3VdbeJumpHere(v, addr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1533 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1534 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1535 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1536 | case TK_EXCEPT: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1537 |     case TK_UNION: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1538 | int unionTab; /* Cursor number of the temporary table holding result */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1539 | int op = 0; /* One of the SRT_ operations to apply to self */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1540 | int priorOp; /* The SRT_ operation to apply to prior selects */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1541 | Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1542 | int addr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1543 | SelectDest uniondest; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1544 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1545 | priorOp = SRT_Union; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1546 |       if( dest.eDest==priorOp && !p->pLimit && !p->pOffset ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1547 | /* We can reuse a temporary table generated by a SELECT to our | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1548 | ** right. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1549 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1550 | unionTab = dest.iParm; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1551 |       }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1552 | /* We will need to create our own temporary table to hold the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1553 | ** intermediate results. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1554 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1555 | unionTab = pParse->nTab++; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1556 | assert( p->pOrderBy==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1557 | addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1558 | assert( p->addrOpenEphm[0] == -1 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1559 | p->addrOpenEphm[0] = addr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1560 | p->pRightmost->selFlags |= SF_UsesEphemeral; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1561 | assert( p->pEList ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1562 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1563 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1564 | /* Code the SELECT statements to our left | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1565 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1566 | assert( !pPrior->pOrderBy ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1567 | sqlite3SelectDestInit(&uniondest, priorOp, unionTab); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1568 | rc = sqlite3Select(pParse, pPrior, &uniondest); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1569 |       if( rc ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1570 | goto multi_select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1571 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1572 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1573 | /* Code the current SELECT statement | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1574 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1575 |       if( p->op==TK_EXCEPT ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1576 | op = SRT_Except; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1577 |       }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1578 | assert( p->op==TK_UNION ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1579 | op = SRT_Union; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1580 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1581 | p->pPrior = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1582 | pLimit = p->pLimit; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1583 | p->pLimit = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1584 | pOffset = p->pOffset; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1585 | p->pOffset = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1586 | uniondest.eDest = op; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1587 | rc = sqlite3Select(pParse, p, &uniondest); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1588 | /* Query flattening in sqlite3Select() might refill p->pOrderBy. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1589 | ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1590 | sqlite3ExprListDelete(db, p->pOrderBy); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1591 | pDelete = p->pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1592 | p->pPrior = pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1593 | p->pOrderBy = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1594 | sqlite3ExprDelete(db, p->pLimit); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1595 | p->pLimit = pLimit; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1596 | p->pOffset = pOffset; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1597 | p->iLimit = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1598 | p->iOffset = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1599 |       if( rc ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1600 | goto multi_select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1601 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1602 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1603 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1604 | /* Convert the data in the temporary table into whatever form | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1605 | ** it is that we currently need. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1606 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1607 |       if( dest.eDest!=priorOp || unionTab!=dest.iParm ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1608 | int iCont, iBreak, iStart; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1609 | assert( p->pEList ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1610 |         if( dest.eDest==SRT_Output ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1611 | Select *pFirst = p; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1612 | while( pFirst->pPrior ) pFirst = pFirst->pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1613 | generateColumnNames(pParse, 0, pFirst->pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1614 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1615 | iBreak = sqlite3VdbeMakeLabel(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1616 | iCont = sqlite3VdbeMakeLabel(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1617 | computeLimitRegisters(pParse, p, iBreak); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1618 | sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1619 | iStart = sqlite3VdbeCurrentAddr(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1620 | selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1621 | 0, -1, &dest, iCont, iBreak); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1622 | sqlite3VdbeResolveLabel(v, iCont); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1623 | sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1624 | sqlite3VdbeResolveLabel(v, iBreak); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1625 | sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1626 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1627 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1628 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1629 |     case TK_INTERSECT: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1630 | int tab1, tab2; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1631 | int iCont, iBreak, iStart; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1632 | Expr *pLimit, *pOffset; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1633 | int addr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1634 | SelectDest intersectdest; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1635 | int r1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1636 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1637 | /* INTERSECT is different from the others since it requires | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1638 | ** two temporary tables. Hence it has its own case. Begin | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1639 | ** by allocating the tables we will need. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1640 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1641 | tab1 = pParse->nTab++; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1642 | tab2 = pParse->nTab++; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1643 | assert( p->pOrderBy==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1644 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1645 | addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1646 | assert( p->addrOpenEphm[0] == -1 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1647 | p->addrOpenEphm[0] = addr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1648 | p->pRightmost->selFlags |= SF_UsesEphemeral; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1649 | assert( p->pEList ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1650 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1651 | /* Code the SELECTs to our left into temporary table "tab1". | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1652 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1653 | sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1654 | rc = sqlite3Select(pParse, pPrior, &intersectdest); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1655 |       if( rc ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1656 | goto multi_select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1657 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1658 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1659 | /* Code the current SELECT into temporary table "tab2" | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1660 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1661 | addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1662 | assert( p->addrOpenEphm[1] == -1 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1663 | p->addrOpenEphm[1] = addr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1664 | p->pPrior = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1665 | pLimit = p->pLimit; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1666 | p->pLimit = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1667 | pOffset = p->pOffset; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1668 | p->pOffset = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1669 | intersectdest.iParm = tab2; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1670 | rc = sqlite3Select(pParse, p, &intersectdest); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1671 | pDelete = p->pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1672 | p->pPrior = pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1673 | sqlite3ExprDelete(db, p->pLimit); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1674 | p->pLimit = pLimit; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1675 | p->pOffset = pOffset; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1676 |       if( rc ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1677 | goto multi_select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1678 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1679 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1680 | /* Generate code to take the intersection of the two temporary | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1681 | ** tables. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1682 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1683 | assert( p->pEList ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1684 |       if( dest.eDest==SRT_Output ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1685 | Select *pFirst = p; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1686 | while( pFirst->pPrior ) pFirst = pFirst->pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1687 | generateColumnNames(pParse, 0, pFirst->pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1688 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1689 | iBreak = sqlite3VdbeMakeLabel(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1690 | iCont = sqlite3VdbeMakeLabel(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1691 | computeLimitRegisters(pParse, p, iBreak); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1692 | sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1693 | r1 = sqlite3GetTempReg(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1694 | iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1695 | sqlite3VdbeAddOp3(v, OP_NotFound, tab2, iCont, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1696 | sqlite3ReleaseTempReg(pParse, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1697 | selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1698 | 0, -1, &dest, iCont, iBreak); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1699 | sqlite3VdbeResolveLabel(v, iCont); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1700 | sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1701 | sqlite3VdbeResolveLabel(v, iBreak); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1702 | sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1703 | sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1704 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1705 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1706 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1707 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1708 | /* Compute collating sequences used by | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1709 | ** temporary tables needed to implement the compound select. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1710 | ** Attach the KeyInfo structure to all temporary tables. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1711 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1712 | ** This section is run by the right-most SELECT statement only. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1713 | ** SELECT statements to the left always skip this part. The right-most | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1714 | ** SELECT might also skip this part if it has no ORDER BY clause and | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1715 | ** no temp tables are required. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1716 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1717 |   if( p->selFlags & SF_UsesEphemeral ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1718 | int i; /* Loop counter */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1719 | KeyInfo *pKeyInfo; /* Collating sequence for the result set */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1720 | Select *pLoop; /* For looping through SELECT statements */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1721 | CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1722 | int nCol; /* Number of columns in result set */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1723 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1724 | assert( p->pRightmost==p ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1725 | nCol = p->pEList->nExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1726 | pKeyInfo = sqlite3DbMallocZero(db, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1727 | sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1728 |     if( !pKeyInfo ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1729 | rc = SQLITE_NOMEM; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1730 | goto multi_select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1731 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1732 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1733 | pKeyInfo->enc = ENC(db); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1734 | pKeyInfo->nField = nCol; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1735 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1736 |     for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1737 | *apColl = multiSelectCollSeq(pParse, p, i); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1738 |       if( 0==*apColl ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1739 | *apColl = db->pDfltColl; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1740 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1741 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1742 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1743 |     for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1744 |       for(i=0; i<2; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1745 | int addr = pLoop->addrOpenEphm[i]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1746 |         if( addr<0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1747 | /* If [0] is unused then [1] is also unused. So we can | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1748 | ** always safely abort as soon as the first unused slot is found */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1749 | assert( pLoop->addrOpenEphm[1]<0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1750 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1751 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1752 | sqlite3VdbeChangeP2(v, addr, nCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1753 | sqlite3VdbeChangeP4(v, addr, (char*)pKeyInfo, P4_KEYINFO); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1754 | pLoop->addrOpenEphm[i] = -1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1755 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1756 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1757 | sqlite3DbFree(db, pKeyInfo); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1758 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1759 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1760 | multi_select_end: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1761 | pDest->iMem = dest.iMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1762 | pDest->nMem = dest.nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1763 | sqlite3SelectDelete(db, pDelete); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1764 | return rc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1765 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1766 | #endif /* SQLITE_OMIT_COMPOUND_SELECT */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1767 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1768 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1769 | ** Code an output subroutine for a coroutine implementation of a | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1770 | ** SELECT statment. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1771 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1772 | ** The data to be output is contained in pIn->iMem. There are | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1773 | ** pIn->nMem columns to be output. pDest is where the output should | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1774 | ** be sent. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1775 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1776 | ** regReturn is the number of the register holding the subroutine | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1777 | ** return address. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1778 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1779 | ** If regPrev>0 then it is a the first register in a vector that | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1780 | ** records the previous output. mem[regPrev] is a flag that is false | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1781 | ** if there has been no previous output. If regPrev>0 then code is | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1782 | ** generated to suppress duplicates. pKeyInfo is used for comparing | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1783 | ** keys. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1784 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1785 | ** If the LIMIT found in p->iLimit is reached, jump immediately to | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1786 | ** iBreak. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1787 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1788 | static int generateOutputSubroutine( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1789 | Parse *pParse, /* Parsing context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1790 | Select *p, /* The SELECT statement */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1791 | SelectDest *pIn, /* Coroutine supplying data */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1792 | SelectDest *pDest, /* Where to send the data */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1793 | int regReturn, /* The return address register */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1794 | int regPrev, /* Previous result register. No uniqueness if 0 */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1795 | KeyInfo *pKeyInfo, /* For comparing with previous entry */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1796 | int p4type, /* The p4 type for pKeyInfo */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1797 | int iBreak /* Jump here if we hit the LIMIT */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1798 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1799 | Vdbe *v = pParse->pVdbe; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1800 | int iContinue; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1801 | int addr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1802 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1803 | addr = sqlite3VdbeCurrentAddr(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1804 | iContinue = sqlite3VdbeMakeLabel(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1805 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1806 | /* Suppress duplicates for UNION, EXCEPT, and INTERSECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1807 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1808 |   if( regPrev ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1809 | int j1, j2; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1810 | j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1811 | j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1812 | (char*)pKeyInfo, p4type); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1813 | sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1814 | sqlite3VdbeJumpHere(v, j1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1815 | sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1816 | sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1817 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1818 | if( pParse->db->mallocFailed ) return 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1819 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1820 | /* Suppress the the first OFFSET entries if there is an OFFSET clause | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1821 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1822 | codeOffset(v, p, iContinue); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1823 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1824 |   switch( pDest->eDest ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1825 | /* Store the result as data using a unique key. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1826 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1827 | case SRT_Table: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1828 |     case SRT_EphemTab: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1829 | int r1 = sqlite3GetTempReg(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1830 | int r2 = sqlite3GetTempReg(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1831 | sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1832 | sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1833 | sqlite3VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1834 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1835 | sqlite3ReleaseTempReg(pParse, r2); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1836 | sqlite3ReleaseTempReg(pParse, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1837 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1838 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1839 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1840 | #ifndef SQLITE_OMIT_SUBQUERY | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1841 | /* If we are creating a set for an "expr IN (SELECT ...)" construct, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1842 | ** then there should be a single item on the stack. Write this | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1843 | ** item into the set table with bogus data. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1844 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1845 |     case SRT_Set: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1846 | int r1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1847 | assert( pIn->nMem==1 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1848 | p->affinity = | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1849 | sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1850 | r1 = sqlite3GetTempReg(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1851 | sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1852 | sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, 1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1853 | sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iParm, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1854 | sqlite3ReleaseTempReg(pParse, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1855 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1856 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1857 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1858 | #if 0 /* Never occurs on an ORDER BY query */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1859 | /* If any row exist in the result set, record that fact and abort. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1860 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1861 |     case SRT_Exists: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1862 | sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iParm); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1863 | /* The LIMIT clause will terminate the loop for us */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1864 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1865 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1866 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1867 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1868 | /* If this is a scalar select that is part of an expression, then | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1869 | ** store the results in the appropriate memory cell and break out | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1870 | ** of the scan loop. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1871 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1872 |     case SRT_Mem: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1873 | assert( pIn->nMem==1 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1874 | sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iParm, 1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1875 | /* The LIMIT clause will jump out of the loop for us */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1876 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1877 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1878 | #endif /* #ifndef SQLITE_OMIT_SUBQUERY */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1879 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1880 | /* The results are stored in a sequence of registers | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1881 | ** starting at pDest->iMem. Then the co-routine yields. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1882 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1883 |     case SRT_Coroutine: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1884 |       if( pDest->iMem==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1885 | pDest->iMem = sqlite3GetTempRange(pParse, pIn->nMem); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1886 | pDest->nMem = pIn->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1887 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1888 | sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iMem, pDest->nMem); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1889 | sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1890 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1891 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1892 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1893 | /* Results are stored in a sequence of registers. Then the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1894 | ** OP_ResultRow opcode is used to cause sqlite3_step() to return | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1895 | ** the next row of result. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1896 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1897 |     case SRT_Output: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1898 | sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iMem, pIn->nMem); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1899 | sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, pIn->nMem); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1900 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1901 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1902 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1903 | #if !defined(SQLITE_OMIT_TRIGGER) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1904 | /* Discard the results. This is used for SELECT statements inside | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1905 | ** the body of a TRIGGER. The purpose of such selects is to call | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1906 | ** user-defined functions that have side effects. We do not care | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1907 | ** about the actual results of the select. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1908 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1909 |     default: {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1910 | break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1911 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1912 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1913 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1914 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1915 | /* Jump to the end of the loop if the LIMIT is reached. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1916 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1917 |   if( p->iLimit ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1918 | sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1919 | sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1920 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1921 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1922 | /* Generate the subroutine return | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1923 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1924 | sqlite3VdbeResolveLabel(v, iContinue); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1925 | sqlite3VdbeAddOp1(v, OP_Return, regReturn); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1926 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1927 | return addr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1928 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1929 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1930 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1931 | ** Alternative compound select code generator for cases when there | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1932 | ** is an ORDER BY clause. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1933 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1934 | ** We assume a query of the following form: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1935 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1936 | ** <selectA> <operator> <selectB> ORDER BY <orderbylist> | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1937 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1938 | ** <operator> is one of UNION ALL, UNION, EXCEPT, or INTERSECT. The idea | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1939 | ** is to code both <selectA> and <selectB> with the ORDER BY clause as | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1940 | ** co-routines. Then run the co-routines in parallel and merge the results | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1941 | ** into the output. In addition to the two coroutines (called selectA and | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1942 | ** selectB) there are 7 subroutines: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1943 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1944 | ** outA: Move the output of the selectA coroutine into the output | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1945 | ** of the compound query. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1946 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1947 | ** outB: Move the output of the selectB coroutine into the output | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1948 | ** of the compound query. (Only generated for UNION and | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1949 | ** UNION ALL. EXCEPT and INSERTSECT never output a row that | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1950 | ** appears only in B.) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1951 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1952 | ** AltB: Called when there is data from both coroutines and A<B. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1953 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1954 | ** AeqB: Called when there is data from both coroutines and A==B. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1955 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1956 | ** AgtB: Called when there is data from both coroutines and A>B. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1957 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1958 | ** EofA: Called when data is exhausted from selectA. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1959 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1960 | ** EofB: Called when data is exhausted from selectB. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1961 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1962 | ** The implementation of the latter five subroutines depend on which | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1963 | ** <operator> is used: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1964 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1965 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1966 | ** UNION ALL UNION EXCEPT INTERSECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1967 | ** ------------- ----------------- -------------- ----------------- | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1968 | ** AltB: outA, nextA outA, nextA outA, nextA nextA | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1969 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1970 | ** AeqB: outA, nextA nextA nextA outA, nextA | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1971 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1972 | ** AgtB: outB, nextB outB, nextB nextB nextB | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1973 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1974 | ** EofA: outB, nextB outB, nextB halt halt | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1975 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1976 | ** EofB: outA, nextA outA, nextA outA, nextA halt | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1977 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1978 | ** In the AltB, AeqB, and AgtB subroutines, an EOF on A following nextA | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1979 | ** causes an immediate jump to EofA and an EOF on B following nextB causes | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1980 | ** an immediate jump to EofB. Within EofA and EofB, and EOF on entry or | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1981 | ** following nextX causes a jump to the end of the select processing. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1982 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1983 | ** Duplicate removal in the UNION, EXCEPT, and INTERSECT cases is handled | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1984 | ** within the output subroutine. The regPrev register set holds the previously | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1985 | ** output value. A comparison is made against this value and the output | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1986 | ** is skipped if the next results would be the same as the previous. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1987 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1988 | ** The implementation plan is to implement the two coroutines and seven | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1989 | ** subroutines first, then put the control logic at the bottom. Like this: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1990 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1991 | ** goto Init | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1992 | ** coA: coroutine for left query (A) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1993 | ** coB: coroutine for right query (B) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1994 | ** outA: output one row of A | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1995 | ** outB: output one row of B (UNION and UNION ALL only) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1996 | ** EofA: ... | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1997 | ** EofB: ... | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1998 | ** AltB: ... | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 1999 | ** AeqB: ... | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2000 | ** AgtB: ... | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2001 | ** Init: initialize coroutine registers | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2002 | ** yield coA | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2003 | ** if eof(A) goto EofA | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2004 | ** yield coB | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2005 | ** if eof(B) goto EofB | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2006 | ** Cmpr: Compare A, B | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2007 | ** Jump AltB, AeqB, AgtB | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2008 | ** End: ... | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2009 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2010 | ** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2011 | ** actually called using Gosub and they do not Return. EofA and EofB loop | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2012 | ** until all data is exhausted then jump to the "end" labe. AltB, AeqB, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2013 | ** and AgtB jump to either L2 or to one of EofA or EofB. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2014 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2015 | #ifndef SQLITE_OMIT_COMPOUND_SELECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2016 | static int multiSelectOrderBy( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2017 | Parse *pParse, /* Parsing context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2018 | Select *p, /* The right-most of SELECTs to be coded */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2019 | SelectDest *pDest /* What to do with query results */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2020 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2021 | int i, j; /* Loop counters */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2022 | Select *pPrior; /* Another SELECT immediately to our left */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2023 | Vdbe *v; /* Generate code to this VDBE */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2024 | SelectDest destA; /* Destination for coroutine A */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2025 | SelectDest destB; /* Destination for coroutine B */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2026 | int regAddrA; /* Address register for select-A coroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2027 | int regEofA; /* Flag to indicate when select-A is complete */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2028 | int regAddrB; /* Address register for select-B coroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2029 | int regEofB; /* Flag to indicate when select-B is complete */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2030 | int addrSelectA; /* Address of the select-A coroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2031 | int addrSelectB; /* Address of the select-B coroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2032 | int regOutA; /* Address register for the output-A subroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2033 | int regOutB; /* Address register for the output-B subroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2034 | int addrOutA; /* Address of the output-A subroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2035 | int addrOutB; /* Address of the output-B subroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2036 | int addrEofA; /* Address of the select-A-exhausted subroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2037 | int addrEofB; /* Address of the select-B-exhausted subroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2038 | int addrAltB; /* Address of the A<B subroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2039 | int addrAeqB; /* Address of the A==B subroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2040 | int addrAgtB; /* Address of the A>B subroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2041 | int regLimitA; /* Limit register for select-A */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2042 | int regLimitB; /* Limit register for select-A */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2043 | int regPrev; /* A range of registers to hold previous output */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2044 | int savedLimit; /* Saved value of p->iLimit */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2045 | int savedOffset; /* Saved value of p->iOffset */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2046 | int labelCmpr; /* Label for the start of the merge algorithm */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2047 | int labelEnd; /* Label for the end of the overall SELECT stmt */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2048 | int j1; /* Jump instructions that get retargetted */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2049 | int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2050 | KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2051 | KeyInfo *pKeyMerge; /* Comparison information for merging rows */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2052 | sqlite3 *db; /* Database connection */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2053 | ExprList *pOrderBy; /* The ORDER BY clause */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2054 | int nOrderBy; /* Number of terms in the ORDER BY clause */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2055 | int *aPermute; /* Mapping from ORDER BY terms to result set columns */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2056 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2057 | assert( p->pOrderBy!=0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2058 | assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2059 | db = pParse->db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2060 | v = pParse->pVdbe; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2061 | if( v==0 ) return SQLITE_NOMEM; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2062 | labelEnd = sqlite3VdbeMakeLabel(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2063 | labelCmpr = sqlite3VdbeMakeLabel(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2064 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2065 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2066 | /* Patch up the ORDER BY clause | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2067 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2068 | op = p->op; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2069 | pPrior = p->pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2070 | assert( pPrior->pOrderBy==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2071 | pOrderBy = p->pOrderBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2072 | assert( pOrderBy ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2073 | nOrderBy = pOrderBy->nExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2074 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2075 | /* For operators other than UNION ALL we have to make sure that | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2076 | ** the ORDER BY clause covers every term of the result set. Add | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2077 | ** terms to the ORDER BY clause as necessary. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2078 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2079 |   if( op!=TK_ALL ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2080 |     for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2081 | struct ExprList_item *pItem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2082 |       for(j=0, pItem=pOrderBy->a; j<nOrderBy; j++, pItem++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2083 | assert( pItem->iCol>0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2084 | if( pItem->iCol==i ) break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2085 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2086 |       if( j==nOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2087 | Expr *pNew = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2088 | if( pNew==0 ) return SQLITE_NOMEM; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2089 | pNew->flags |= EP_IntValue; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2090 | pNew->iTable = i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2091 | pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2092 | pOrderBy->a[nOrderBy++].iCol = i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2093 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2094 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2095 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2096 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2097 | /* Compute the comparison permutation and keyinfo that is used with | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2098 | ** the permutation in order to comparisons to determine if the next | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2099 | ** row of results comes from selectA or selectB. Also add explicit | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2100 | ** collations to the ORDER BY clause terms so that when the subqueries | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2101 | ** to the right and the left are evaluated, they use the correct | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2102 | ** collation. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2103 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2104 | aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2105 |   if( aPermute ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2106 | struct ExprList_item *pItem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2107 |     for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2108 | assert( pItem->iCol>0 && pItem->iCol<=p->pEList->nExpr ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2109 | aPermute[i] = pItem->iCol - 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2110 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2111 | pKeyMerge = | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2112 | sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2113 |     if( pKeyMerge ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2114 | pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2115 | pKeyMerge->nField = nOrderBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2116 | pKeyMerge->enc = ENC(db); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2117 |       for(i=0; i<nOrderBy; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2118 | CollSeq *pColl; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2119 | Expr *pTerm = pOrderBy->a[i].pExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2120 |         if( pTerm->flags & EP_ExpCollate ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2121 | pColl = pTerm->pColl; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2122 |         }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2123 | pColl = multiSelectCollSeq(pParse, p, aPermute[i]); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2124 | pTerm->flags |= EP_ExpCollate; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2125 | pTerm->pColl = pColl; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2126 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2127 | pKeyMerge->aColl[i] = pColl; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2128 | pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2129 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2130 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2131 |   }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2132 | pKeyMerge = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2133 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2134 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2135 | /* Reattach the ORDER BY clause to the query. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2136 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2137 | p->pOrderBy = pOrderBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2138 | pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2139 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2140 | /* Allocate a range of temporary registers and the KeyInfo needed | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2141 | ** for the logic that removes duplicate result rows when the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2142 | ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL). | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2143 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2144 |   if( op==TK_ALL ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2145 | regPrev = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2146 |   }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2147 | int nExpr = p->pEList->nExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2148 | assert( nOrderBy>=nExpr ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2149 | regPrev = sqlite3GetTempRange(pParse, nExpr+1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2150 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2151 | pKeyDup = sqlite3DbMallocZero(db, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2152 | sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2153 |     if( pKeyDup ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2154 | pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2155 | pKeyDup->nField = nExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2156 | pKeyDup->enc = ENC(db); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2157 |       for(i=0; i<nExpr; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2158 | pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2159 | pKeyDup->aSortOrder[i] = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2160 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2161 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2162 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2163 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2164 | /* Separate the left and the right query from one another | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2165 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2166 | p->pPrior = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2167 | pPrior->pRightmost = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2168 | sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER"); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2169 |   if( pPrior->pPrior==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2170 | sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2171 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2172 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2173 | /* Compute the limit registers */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2174 | computeLimitRegisters(pParse, p, labelEnd); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2175 |   if( p->iLimit && op==TK_ALL ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2176 | regLimitA = ++pParse->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2177 | regLimitB = ++pParse->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2178 | sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2179 | regLimitA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2180 | sqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2181 |   }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2182 | regLimitA = regLimitB = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2183 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2184 | sqlite3ExprDelete(db, p->pLimit); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2185 | p->pLimit = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2186 | sqlite3ExprDelete(db, p->pOffset); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2187 | p->pOffset = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2188 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2189 | regAddrA = ++pParse->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2190 | regEofA = ++pParse->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2191 | regAddrB = ++pParse->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2192 | regEofB = ++pParse->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2193 | regOutA = ++pParse->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2194 | regOutB = ++pParse->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2195 | sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2196 | sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2197 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2198 | /* Jump past the various subroutines and coroutines to the main | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2199 | ** merge loop | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2200 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2201 | j1 = sqlite3VdbeAddOp0(v, OP_Goto); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2202 | addrSelectA = sqlite3VdbeCurrentAddr(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2203 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2204 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2205 | /* Generate a coroutine to evaluate the SELECT statement to the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2206 | ** left of the compound operator - the "A" select. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2207 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2208 | VdbeNoopComment((v, "Begin coroutine for left SELECT")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2209 | pPrior->iLimit = regLimitA; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2210 | sqlite3Select(pParse, pPrior, &destA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2211 | sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2212 | sqlite3VdbeAddOp1(v, OP_Yield, regAddrA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2213 | VdbeNoopComment((v, "End coroutine for left SELECT")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2214 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2215 | /* Generate a coroutine to evaluate the SELECT statement on | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2216 | ** the right - the "B" select | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2217 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2218 | addrSelectB = sqlite3VdbeCurrentAddr(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2219 | VdbeNoopComment((v, "Begin coroutine for right SELECT")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2220 | savedLimit = p->iLimit; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2221 | savedOffset = p->iOffset; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2222 | p->iLimit = regLimitB; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2223 | p->iOffset = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2224 | sqlite3Select(pParse, p, &destB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2225 | p->iLimit = savedLimit; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2226 | p->iOffset = savedOffset; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2227 | sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2228 | sqlite3VdbeAddOp1(v, OP_Yield, regAddrB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2229 | VdbeNoopComment((v, "End coroutine for right SELECT")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2230 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2231 | /* Generate a subroutine that outputs the current row of the A | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2232 | ** select as the next output row of the compound select. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2233 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2234 | VdbeNoopComment((v, "Output routine for A")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2235 | addrOutA = generateOutputSubroutine(pParse, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2236 | p, &destA, pDest, regOutA, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2237 | regPrev, pKeyDup, P4_KEYINFO_HANDOFF, labelEnd); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2238 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2239 | /* Generate a subroutine that outputs the current row of the B | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2240 | ** select as the next output row of the compound select. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2241 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2242 |   if( op==TK_ALL || op==TK_UNION ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2243 | VdbeNoopComment((v, "Output routine for B")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2244 | addrOutB = generateOutputSubroutine(pParse, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2245 | p, &destB, pDest, regOutB, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2246 | regPrev, pKeyDup, P4_KEYINFO_STATIC, labelEnd); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2247 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2248 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2249 | /* Generate a subroutine to run when the results from select A | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2250 | ** are exhausted and only data in select B remains. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2251 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2252 | VdbeNoopComment((v, "eof-A subroutine")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2253 |   if( op==TK_EXCEPT || op==TK_INTERSECT ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2254 | addrEofA = sqlite3VdbeAddOp2(v, OP_Goto, 0, labelEnd); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2255 |   }else{  
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2256 | addrEofA = sqlite3VdbeAddOp2(v, OP_If, regEofB, labelEnd); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2257 | sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2258 | sqlite3VdbeAddOp1(v, OP_Yield, regAddrB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2259 | sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2260 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2261 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2262 | /* Generate a subroutine to run when the results from select B | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2263 | ** are exhausted and only data in select A remains. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2264 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2265 |   if( op==TK_INTERSECT ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2266 | addrEofB = addrEofA; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2267 |   }else{  
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2268 | VdbeNoopComment((v, "eof-B subroutine")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2269 | addrEofB = sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2270 | sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2271 | sqlite3VdbeAddOp1(v, OP_Yield, regAddrA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2272 | sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2273 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2274 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2275 | /* Generate code to handle the case of A<B | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2276 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2277 | VdbeNoopComment((v, "A-lt-B subroutine")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2278 | addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2279 | sqlite3VdbeAddOp1(v, OP_Yield, regAddrA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2280 | sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2281 | sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2282 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2283 | /* Generate code to handle the case of A==B | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2284 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2285 |   if( op==TK_ALL ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2286 | addrAeqB = addrAltB; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2287 |   }else if( op==TK_INTERSECT ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2288 | addrAeqB = addrAltB; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2289 | addrAltB++; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2290 |   }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2291 | VdbeNoopComment((v, "A-eq-B subroutine")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2292 | addrAeqB = | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2293 | sqlite3VdbeAddOp1(v, OP_Yield, regAddrA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2294 | sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2295 | sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2296 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2297 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2298 | /* Generate code to handle the case of A>B | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2299 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2300 | VdbeNoopComment((v, "A-gt-B subroutine")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2301 | addrAgtB = sqlite3VdbeCurrentAddr(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2302 |   if( op==TK_ALL || op==TK_UNION ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2303 | sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2304 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2305 | sqlite3VdbeAddOp1(v, OP_Yield, regAddrB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2306 | sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2307 | sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2308 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2309 | /* This code runs once to initialize everything. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2310 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2311 | sqlite3VdbeJumpHere(v, j1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2312 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2313 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2314 | sqlite3VdbeAddOp2(v, OP_Gosub, regAddrA, addrSelectA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2315 | sqlite3VdbeAddOp2(v, OP_Gosub, regAddrB, addrSelectB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2316 | sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2317 | sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2318 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2319 | /* Implement the main merge loop | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2320 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2321 | sqlite3VdbeResolveLabel(v, labelCmpr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2322 | sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2323 | sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2324 | (char*)pKeyMerge, P4_KEYINFO_HANDOFF); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2325 | sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2326 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2327 | /* Release temporary registers | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2328 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2329 |   if( regPrev ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2330 | sqlite3ReleaseTempRange(pParse, regPrev, nOrderBy+1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2331 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2332 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2333 | /* Jump to the this point in order to terminate the query. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2334 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2335 | sqlite3VdbeResolveLabel(v, labelEnd); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2336 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2337 | /* Set the number of output columns | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2338 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2339 |   if( pDest->eDest==SRT_Output ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2340 | Select *pFirst = pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2341 | while( pFirst->pPrior ) pFirst = pFirst->pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2342 | generateColumnNames(pParse, 0, pFirst->pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2343 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2344 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2345 | /* Reassembly the compound query so that it will be freed correctly | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2346 | ** by the calling function */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2347 |   if( p->pPrior ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2348 | sqlite3SelectDelete(db, p->pPrior); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2349 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2350 | p->pPrior = pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2351 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2352 | /*** TBD: Insert subroutine calls to close cursors on incomplete | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2353 | **** subqueries ****/ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2354 | return SQLITE_OK; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2355 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2356 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2357 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2358 | #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2359 | /* Forward Declarations */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2360 | static void substExprList(sqlite3*, ExprList*, int, ExprList*); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2361 | static void substSelect(sqlite3*, Select *, int, ExprList *); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2362 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2363 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2364 | ** Scan through the expression pExpr. Replace every reference to | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2365 | ** a column in table number iTable with a copy of the iColumn-th | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2366 | ** entry in pEList. (But leave references to the ROWID column | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2367 | ** unchanged.) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2368 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2369 | ** This routine is part of the flattening procedure. A subquery | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2370 | ** whose result set is defined by pEList appears as entry in the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2371 | ** FROM clause of a SELECT such that the VDBE cursor assigned to that | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2372 | ** FORM clause entry is iTable. This routine make the necessary | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2373 | ** changes to pExpr so that it refers directly to the source table | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2374 | ** of the subquery rather the result set of the subquery. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2375 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2376 | static void substExpr( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2377 | sqlite3 *db, /* Report malloc errors to this connection */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2378 | Expr *pExpr, /* Expr in which substitution occurs */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2379 | int iTable, /* Table to be substituted */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2380 | ExprList *pEList /* Substitute expressions */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2381 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2382 | if( pExpr==0 ) return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2383 |   if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2384 |     if( pExpr->iColumn<0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2385 | pExpr->op = TK_NULL; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2386 |     }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2387 | Expr *pNew; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2388 | assert( pEList!=0 && pExpr->iColumn<pEList->nExpr ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2389 | assert( pExpr->pLeft==0 && pExpr->pRight==0 && pExpr->pList==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2390 | pNew = pEList->a[pExpr->iColumn].pExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2391 | assert( pNew!=0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2392 | pExpr->op = pNew->op; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2393 | assert( pExpr->pLeft==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2394 | pExpr->pLeft = sqlite3ExprDup(db, pNew->pLeft); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2395 | assert( pExpr->pRight==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2396 | pExpr->pRight = sqlite3ExprDup(db, pNew->pRight); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2397 | assert( pExpr->pList==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2398 | pExpr->pList = sqlite3ExprListDup(db, pNew->pList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2399 | pExpr->iTable = pNew->iTable; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2400 | pExpr->pTab = pNew->pTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2401 | pExpr->iColumn = pNew->iColumn; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2402 | pExpr->iAgg = pNew->iAgg; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2403 | sqlite3TokenCopy(db, &pExpr->token, &pNew->token); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2404 | sqlite3TokenCopy(db, &pExpr->span, &pNew->span); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2405 | pExpr->pSelect = sqlite3SelectDup(db, pNew->pSelect); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2406 | pExpr->flags = pNew->flags; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2407 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2408 |   }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2409 | substExpr(db, pExpr->pLeft, iTable, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2410 | substExpr(db, pExpr->pRight, iTable, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2411 | substSelect(db, pExpr->pSelect, iTable, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2412 | substExprList(db, pExpr->pList, iTable, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2413 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2414 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2415 | static void substExprList( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2416 | sqlite3 *db, /* Report malloc errors here */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2417 | ExprList *pList, /* List to scan and in which to make substitutes */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2418 | int iTable, /* Table to be substituted */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2419 | ExprList *pEList /* Substitute values */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2420 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2421 | int i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2422 | if( pList==0 ) return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2423 |   for(i=0; i<pList->nExpr; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2424 | substExpr(db, pList->a[i].pExpr, iTable, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2425 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2426 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2427 | static void substSelect( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2428 | sqlite3 *db, /* Report malloc errors here */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2429 | Select *p, /* SELECT statement in which to make substitutions */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2430 | int iTable, /* Table to be replaced */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2431 | ExprList *pEList /* Substitute values */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2432 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2433 | SrcList *pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2434 | struct SrcList_item *pItem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2435 | int i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2436 | if( !p ) return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2437 | substExprList(db, p->pEList, iTable, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2438 | substExprList(db, p->pGroupBy, iTable, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2439 | substExprList(db, p->pOrderBy, iTable, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2440 | substExpr(db, p->pHaving, iTable, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2441 | substExpr(db, p->pWhere, iTable, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2442 | substSelect(db, p->pPrior, iTable, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2443 | pSrc = p->pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2444 |   if( pSrc ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2445 |     for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2446 | substSelect(db, pItem->pSelect, iTable, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2447 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2448 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2449 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2450 | #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2451 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2452 | #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2453 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2454 | ** This routine attempts to flatten subqueries in order to speed | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2455 | ** execution. It returns 1 if it makes changes and 0 if no flattening | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2456 | ** occurs. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2457 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2458 | ** To understand the concept of flattening, consider the following | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2459 | ** query: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2460 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2461 | ** SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2462 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2463 | ** The default way of implementing this query is to execute the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2464 | ** subquery first and store the results in a temporary table, then | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2465 | ** run the outer query on that temporary table. This requires two | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2466 | ** passes over the data. Furthermore, because the temporary table | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2467 | ** has no indices, the WHERE clause on the outer query cannot be | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2468 | ** optimized. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2469 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2470 | ** This routine attempts to rewrite queries such as the above into | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2471 | ** a single flat select, like this: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2472 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2473 | ** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2474 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2475 | ** The code generated for this simpification gives the same result | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2476 | ** but only has to scan the data once. And because indices might | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2477 | ** exist on the table t1, a complete scan of the data might be | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2478 | ** avoided. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2479 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2480 | ** Flattening is only attempted if all of the following are true: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2481 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2482 | ** (1) The subquery and the outer query do not both use aggregates. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2483 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2484 | ** (2) The subquery is not an aggregate or the outer query is not a join. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2485 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2486 | ** (3) The subquery is not the right operand of a left outer join | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2487 | ** (Originally ticket #306. Strenghtened by ticket #3300) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2488 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2489 | ** (4) The subquery is not DISTINCT or the outer query is not a join. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2490 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2491 | ** (5) The subquery is not DISTINCT or the outer query does not use | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2492 | ** aggregates. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2493 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2494 | ** (6) The subquery does not use aggregates or the outer query is not | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2495 | ** DISTINCT. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2496 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2497 | ** (7) The subquery has a FROM clause. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2498 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2499 | ** (8) The subquery does not use LIMIT or the outer query is not a join. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2500 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2501 | ** (9) The subquery does not use LIMIT or the outer query does not use | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2502 | ** aggregates. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2503 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2504 | ** (10) The subquery does not use aggregates or the outer query does not | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2505 | ** use LIMIT. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2506 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2507 | ** (11) The subquery and the outer query do not both have ORDER BY clauses. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2508 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2509 | ** (12) Not implemented. Subsumed into restriction (3). Was previously | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2510 | ** a separate restriction deriving from ticket #350. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2511 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2512 | ** (13) The subquery and outer query do not both use LIMIT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2513 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2514 | ** (14) The subquery does not use OFFSET | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2515 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2516 | ** (15) The outer query is not part of a compound select or the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2517 | ** subquery does not have both an ORDER BY and a LIMIT clause. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2518 | ** (See ticket #2339) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2519 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2520 | ** (16) The outer query is not an aggregate or the subquery does | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2521 | ** not contain ORDER BY. (Ticket #2942) This used to not matter | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2522 | ** until we introduced the group_concat() function. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2523 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2524 | ** (17) The sub-query is not a compound select, or it is a UNION ALL | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2525 | ** compound clause made up entirely of non-aggregate queries, and | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2526 | ** the parent query: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2527 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2528 | ** * is not itself part of a compound select, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2529 | ** * is not an aggregate or DISTINCT query, and | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2530 | ** * has no other tables or sub-selects in the FROM clause. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2531 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2532 | ** The parent and sub-query may contain WHERE clauses. Subject to | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2533 | ** rules (11), (13) and (14), they may also contain ORDER BY, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2534 | ** LIMIT and OFFSET clauses. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2535 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2536 | ** (18) If the sub-query is a compound select, then all terms of the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2537 | ** ORDER by clause of the parent must be simple references to | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2538 | ** columns of the sub-query. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2539 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2540 | ** (19) The subquery does not use LIMIT or the outer query does not | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2541 | ** have a WHERE clause. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2542 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2543 | ** In this routine, the "p" parameter is a pointer to the outer query. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2544 | ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2545 | ** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2546 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2547 | ** If flattening is not attempted, this routine is a no-op and returns 0. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2548 | ** If flattening is attempted this routine returns 1. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2549 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2550 | ** All of the expression analysis must occur on both the outer query and | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2551 | ** the subquery before this routine runs. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2552 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2553 | static int flattenSubquery( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2554 | Parse *pParse, /* Parsing context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2555 | Select *p, /* The parent or outer SELECT statement */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2556 | int iFrom, /* Index in p->pSrc->a[] of the inner subquery */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2557 | int isAgg, /* True if outer SELECT uses aggregate functions */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2558 | int subqueryIsAgg /* True if the subquery uses aggregate functions */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2559 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2560 | const char *zSavedAuthContext = pParse->zAuthContext; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2561 | Select *pParent; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2562 | Select *pSub; /* The inner query or "subquery" */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2563 | Select *pSub1; /* Pointer to the rightmost select in sub-query */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2564 | SrcList *pSrc; /* The FROM clause of the outer query */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2565 | SrcList *pSubSrc; /* The FROM clause of the subquery */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2566 | ExprList *pList; /* The result set of the outer query */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2567 | int iParent; /* VDBE cursor number of the pSub result set temp table */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2568 | int i; /* Loop counter */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2569 | Expr *pWhere; /* The WHERE clause */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2570 | struct SrcList_item *pSubitem; /* The subquery */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2571 | sqlite3 *db = pParse->db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2572 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2573 | /* Check to see if flattening is permitted. Return 0 if not. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2574 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2575 | if( p==0 ) return 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2576 | pSrc = p->pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2577 | assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2578 | pSubitem = &pSrc->a[iFrom]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2579 | iParent = pSubitem->iCursor; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2580 | pSub = pSubitem->pSelect; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2581 | assert( pSub!=0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2582 | if( isAgg && subqueryIsAgg ) return 0; /* Restriction (1) */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2583 | if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; /* Restriction (2) */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2584 | pSubSrc = pSub->pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2585 | assert( pSubSrc ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2586 | /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2587 | ** not arbitrary expresssions, we allowed some combining of LIMIT and OFFSET | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2588 | ** because they could be computed at compile-time. But when LIMIT and OFFSET | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2589 | ** became arbitrary expressions, we were forced to add restrictions (13) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2590 | ** and (14). */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2591 | if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2592 | if( pSub->pOffset ) return 0; /* Restriction (14) */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2593 |   if( p->pRightmost && pSub->pLimit && pSub->pOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2594 | return 0; /* Restriction (15) */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2595 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2596 | if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2597 | if( ((pSub->selFlags & SF_Distinct)!=0 || pSub->pLimit) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2598 |          && (pSrc->nSrc>1 || isAgg) ){          /* Restrictions (4)(5)(8)(9) */
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2599 | return 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2600 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2601 |   if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2602 | return 0; /* Restriction (6) */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2603 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2604 |   if( p->pOrderBy && pSub->pOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2605 | return 0; /* Restriction (11) */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2606 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2607 | if( isAgg && pSub->pOrderBy ) return 0; /* Restriction (16) */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2608 | if( pSub->pLimit && p->pWhere ) return 0; /* Restriction (19) */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2609 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2610 | /* OBSOLETE COMMENT 1: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2611 | ** Restriction 3: If the subquery is a join, make sure the subquery is | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2612 | ** not used as the right operand of an outer join. Examples of why this | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2613 | ** is not allowed: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2614 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2615 | ** t1 LEFT OUTER JOIN (t2 JOIN t3) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2616 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2617 | ** If we flatten the above, we would get | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2618 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2619 | ** (t1 LEFT OUTER JOIN t2) JOIN t3 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2620 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2621 | ** which is not at all the same thing. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2622 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2623 | ** OBSOLETE COMMENT 2: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2624 | ** Restriction 12: If the subquery is the right operand of a left outer | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2625 | ** join, make sure the subquery has no WHERE clause. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2626 | ** An examples of why this is not allowed: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2627 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2628 | ** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2629 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2630 | ** If we flatten the above, we would get | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2631 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2632 | ** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2633 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2634 | ** But the t2.x>0 test will always fail on a NULL row of t2, which | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2635 | ** effectively converts the OUTER JOIN into an INNER JOIN. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2636 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2637 | ** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2638 | ** Ticket #3300 shows that flattening the right term of a LEFT JOIN | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2639 | ** is fraught with danger. Best to avoid the whole thing. If the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2640 | ** subquery is the right term of a LEFT JOIN, then do not flatten. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2641 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2642 |   if( (pSubitem->jointype & JT_OUTER)!=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2643 | return 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2644 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2645 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2646 | /* Restriction 17: If the sub-query is a compound SELECT, then it must | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2647 | ** use only the UNION ALL operator. And none of the simple select queries | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2648 | ** that make up the compound SELECT are allowed to be aggregate or distinct | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2649 | ** queries. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2650 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2651 |   if( pSub->pPrior ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2652 |     if( p->pPrior || isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2653 | return 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2654 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2655 |     for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2656 | if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2657 | || (pSub1->pPrior && pSub1->op!=TK_ALL) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2658 | || !pSub1->pSrc || pSub1->pSrc->nSrc!=1 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2659 |       ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2660 | return 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2661 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2662 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2663 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2664 | /* Restriction 18. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2665 |     if( p->pOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2666 | int ii; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2667 |       for(ii=0; ii<p->pOrderBy->nExpr; ii++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2668 | if( p->pOrderBy->a[ii].iCol==0 ) return 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2669 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2670 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2671 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2672 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2673 | /***** If we reach this point, flattening is permitted. *****/ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2674 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2675 | /* Authorize the subquery */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2676 | pParse->zAuthContext = pSubitem->zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2677 | sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2678 | pParse->zAuthContext = zSavedAuthContext; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2679 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2680 | /* If the sub-query is a compound SELECT statement, then (by restrictions | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2681 | ** 17 and 18 above) it must be a UNION ALL and the parent query must | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2682 | ** be of the form: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2683 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2684 | ** SELECT <expr-list> FROM (<sub-query>) <where-clause> | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2685 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2686 | ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2687 | ** creates N copies of the parent query without any ORDER BY, LIMIT or | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2688 | ** OFFSET clauses and joins them to the left-hand-side of the original | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2689 | ** using UNION ALL operators. In this case N is the number of simple | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2690 | ** select statements in the compound sub-query. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2691 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2692 |   for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2693 | Select *pNew; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2694 | ExprList *pOrderBy = p->pOrderBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2695 | Expr *pLimit = p->pLimit; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2696 | Expr *pOffset = p->pOffset; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2697 | Select *pPrior = p->pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2698 | p->pOrderBy = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2699 | p->pSrc = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2700 | p->pPrior = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2701 | p->pLimit = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2702 | pNew = sqlite3SelectDup(db, p); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2703 | pNew->pPrior = pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2704 | p->pPrior = pNew; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2705 | p->pOrderBy = pOrderBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2706 | p->op = TK_ALL; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2707 | p->pSrc = pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2708 | p->pLimit = pLimit; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2709 | p->pOffset = pOffset; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2710 | p->pRightmost = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2711 | pNew->pRightmost = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2712 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2713 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2714 | /* Begin flattening the iFrom-th entry of the FROM clause | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2715 | ** in the outer query. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2716 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2717 | pSub = pSub1 = pSubitem->pSelect; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2718 |   for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2719 | int nSubSrc = pSubSrc->nSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2720 | int jointype = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2721 | pSubSrc = pSub->pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2722 | pSrc = pParent->pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2723 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2724 | /* Move all of the FROM elements of the subquery into the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2725 | ** the FROM clause of the outer query. Before doing this, remember | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2726 | ** the cursor number for the original outer query FROM element in | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2727 | ** iParent. The iParent cursor will never be used. Subsequent code | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2728 | ** will scan expressions looking for iParent references and replace | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2729 | ** those references with expressions that resolve to the subquery FROM | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2730 | ** elements we are now copying in. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2731 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2732 |     if( pSrc ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2733 | Table *pTabToDel; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2734 | pSubitem = &pSrc->a[iFrom]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2735 | nSubSrc = pSubSrc->nSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2736 | jointype = pSubitem->jointype; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2737 | sqlite3DbFree(db, pSubitem->zDatabase); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2738 | sqlite3DbFree(db, pSubitem->zName); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2739 | sqlite3DbFree(db, pSubitem->zAlias); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2740 | pSubitem->zDatabase = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2741 | pSubitem->zName = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2742 | pSubitem->zAlias = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2743 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2744 | /* If the FROM element is a subquery, defer deleting the Table | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2745 | ** object associated with that subquery until code generation is | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2746 | ** complete, since there may still exist Expr.pTab entires that | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2747 | ** refer to the subquery even after flattening. Ticket #3346. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2748 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2749 |       if( (pTabToDel = pSubitem->pTab)!=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2750 |         if( pTabToDel->nRef==1 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2751 | pTabToDel->pNextZombie = pParse->pZombieTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2752 | pParse->pZombieTab = pTabToDel; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2753 |         }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2754 | pTabToDel->nRef--; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2755 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2756 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2757 | pSubitem->pTab = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2758 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2759 |     if( nSubSrc!=1 || !pSrc ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2760 | int extra = nSubSrc - 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2761 |       for(i=(pSrc?1:0); i<nSubSrc; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2762 | pSrc = sqlite3SrcListAppend(db, pSrc, 0, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2763 |         if( pSrc==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2764 | pParent->pSrc = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2765 | return 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2766 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2767 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2768 | pParent->pSrc = pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2769 |       for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2770 | pSrc->a[i] = pSrc->a[i-extra]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2771 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2772 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2773 |     for(i=0; i<nSubSrc; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2774 | pSrc->a[i+iFrom] = pSubSrc->a[i]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2775 | memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2776 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2777 | pSrc->a[iFrom].jointype = jointype; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2778 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2779 | /* Now begin substituting subquery result set expressions for | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2780 | ** references to the iParent in the outer query. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2781 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2782 | ** Example: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2783 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2784 | ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2785 | ** \ \_____________ subquery __________/ / | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2786 | ** \_____________________ outer query ______________________________/ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2787 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2788 | ** We look at every expression in the outer query and every place we see | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2789 | ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10". | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2790 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2791 | pList = pParent->pEList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2792 |     for(i=0; i<pList->nExpr; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2793 | Expr *pExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2794 |       if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2795 | pList->a[i].zName = | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2796 | sqlite3DbStrNDup(db, (char*)pExpr->span.z, pExpr->span.n); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2797 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2798 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2799 | substExprList(db, pParent->pEList, iParent, pSub->pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2800 |     if( isAgg ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2801 | substExprList(db, pParent->pGroupBy, iParent, pSub->pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2802 | substExpr(db, pParent->pHaving, iParent, pSub->pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2803 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2804 |     if( pSub->pOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2805 | assert( pParent->pOrderBy==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2806 | pParent->pOrderBy = pSub->pOrderBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2807 | pSub->pOrderBy = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2808 |     }else if( pParent->pOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2809 | substExprList(db, pParent->pOrderBy, iParent, pSub->pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2810 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2811 |     if( pSub->pWhere ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2812 | pWhere = sqlite3ExprDup(db, pSub->pWhere); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2813 |     }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2814 | pWhere = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2815 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2816 |     if( subqueryIsAgg ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2817 | assert( pParent->pHaving==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2818 | pParent->pHaving = pParent->pWhere; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2819 | pParent->pWhere = pWhere; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2820 | substExpr(db, pParent->pHaving, iParent, pSub->pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2821 | pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2822 | sqlite3ExprDup(db, pSub->pHaving)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2823 | assert( pParent->pGroupBy==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2824 | pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2825 |     }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2826 | substExpr(db, pParent->pWhere, iParent, pSub->pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2827 | pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2828 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2829 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2830 | /* The flattened query is distinct if either the inner or the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2831 | ** outer query is distinct. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2832 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2833 | pParent->selFlags |= pSub->selFlags & SF_Distinct; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2834 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2835 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2836 | ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2837 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2838 | ** One is tempted to try to add a and b to combine the limits. But this | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2839 | ** does not work if either limit is negative. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2840 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2841 |     if( pSub->pLimit ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2842 | pParent->pLimit = pSub->pLimit; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2843 | pSub->pLimit = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2844 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2845 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2846 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2847 | /* Finially, delete what is left of the subquery and return | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2848 | ** success. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2849 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2850 | sqlite3SelectDelete(db, pSub1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2851 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2852 | return 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2853 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2854 | #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2855 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2856 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2857 | ** Analyze the SELECT statement passed as an argument to see if it | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2858 | ** is a min() or max() query. Return WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX if | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2859 | ** it is, or 0 otherwise. At present, a query is considered to be | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2860 | ** a min()/max() query if: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2861 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2862 | ** 1. There is a single object in the FROM clause. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2863 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2864 | ** 2. There is a single expression in the result set, and it is | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2865 | ** either min(x) or max(x), where x is a column reference. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2866 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2867 | static int minMaxQuery(Parse *pParse, Select *p){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2868 | Expr *pExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2869 | ExprList *pEList = p->pEList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2870 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2871 | if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2872 | pExpr = pEList->a[0].pExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2873 | pEList = pExpr->pList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2874 | if( pExpr->op!=TK_AGG_FUNCTION || pEList==0 || pEList->nExpr!=1 ) return 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2875 | if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2876 | if( pExpr->token.n!=3 ) return WHERE_ORDERBY_NORMAL; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2877 |   if( sqlite3StrNICmp((char*)pExpr->token.z,"min",3)==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2878 | return WHERE_ORDERBY_MIN; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2879 |   }else if( sqlite3StrNICmp((char*)pExpr->token.z,"max",3)==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2880 | return WHERE_ORDERBY_MAX; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2881 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2882 | return WHERE_ORDERBY_NORMAL; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2883 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2884 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2885 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2886 | ** This routine is a Walker callback for "expanding" a SELECT statement. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2887 | ** "Expanding" means to do the following: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2888 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2889 | ** (1) Make sure VDBE cursor numbers have been assigned to every | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2890 | ** element of the FROM clause. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2891 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2892 | ** (2) Fill in the pTabList->a[].pTab fields in the SrcList that | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2893 | ** defines FROM clause. When views appear in the FROM clause, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2894 | ** fill pTabList->a[].pSelect with a copy of the SELECT statement | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2895 | ** that implements the view. A copy is made of the view's SELECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2896 | ** statement so that we can freely modify or delete that statement | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2897 | ** without worrying about messing up the presistent representation | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2898 | ** of the view. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2899 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2900 | ** (3) Add terms to the WHERE clause to accomodate the NATURAL keyword | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2901 | ** on joins and the ON and USING clause of joins. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2902 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2903 | ** (4) Scan the list of columns in the result set (pEList) looking | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2904 | ** for instances of the "*" operator or the TABLE.* operator. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2905 | ** If found, expand each "*" to be every column in every table | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2906 | ** and TABLE.* to be every column in TABLE. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2907 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2908 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2909 | static int selectExpander(Walker *pWalker, Select *p){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2910 | Parse *pParse = pWalker->pParse; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2911 | int i, j, k; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2912 | SrcList *pTabList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2913 | ExprList *pEList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2914 | struct SrcList_item *pFrom; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2915 | sqlite3 *db = pParse->db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2916 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2917 |   if( db->mallocFailed  ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2918 | return WRC_Abort; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2919 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2920 |   if( p->pSrc==0 || (p->selFlags & SF_Expanded)!=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2921 | return WRC_Prune; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2922 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2923 | p->selFlags |= SF_Expanded; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2924 | pTabList = p->pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2925 | pEList = p->pEList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2926 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2927 | /* Make sure cursor numbers have been assigned to all entries in | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2928 | ** the FROM clause of the SELECT statement. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2929 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2930 | sqlite3SrcListAssignCursors(pParse, pTabList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2931 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2932 | /* Look up every table named in the FROM clause of the select. If | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2933 | ** an entry of the FROM clause is a subquery instead of a table or view, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2934 | ** then create a transient table structure to describe the subquery. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2935 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2936 |   for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2937 | Table *pTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2938 |     if( pFrom->pTab!=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2939 | /* This statement has already been prepared. There is no need | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2940 | ** to go further. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2941 | assert( i==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2942 | return WRC_Prune; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2943 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2944 |     if( pFrom->zName==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2945 | #ifndef SQLITE_OMIT_SUBQUERY | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2946 | Select *pSel = pFrom->pSelect; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2947 | /* A sub-query in the FROM clause of a SELECT */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2948 | assert( pSel!=0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2949 | assert( pFrom->pTab==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2950 | sqlite3WalkSelect(pWalker, pSel); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2951 | pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2952 | if( pTab==0 ) return WRC_Abort; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2953 | pTab->db = db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2954 | pTab->nRef = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2955 | pTab->zName = sqlite3MPrintf(db, "sqlite_subquery_%p_", (void*)pTab); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2956 |       while( pSel->pPrior ){ pSel = pSel->pPrior; }
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2957 | selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2958 | pTab->iPKey = -1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2959 | pTab->tabFlags |= TF_Ephemeral; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2960 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2961 |     }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2962 | /* An ordinary table or view name in the FROM clause */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2963 | assert( pFrom->pTab==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2964 | pFrom->pTab = pTab = | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2965 | sqlite3LocateTable(pParse,0,pFrom->zName,pFrom->zDatabase); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2966 | if( pTab==0 ) return WRC_Abort; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2967 | pTab->nRef++; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2968 | #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2969 |       if( pTab->pSelect || IsVirtual(pTab) ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2970 | /* We reach here if the named table is a really a view */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2971 | if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2972 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2973 | /* If pFrom->pSelect!=0 it means we are dealing with a | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2974 | ** view within a view. The SELECT structure has already been | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2975 | ** copied by the outer view so we can skip the copy step here | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2976 | ** in the inner view. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2977 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2978 |         if( pFrom->pSelect==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2979 | pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2980 | sqlite3WalkSelect(pWalker, pFrom->pSelect); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2981 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2982 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2983 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2984 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2985 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2986 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2987 | /* Process NATURAL keywords, and ON and USING clauses of joins. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2988 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2989 |   if( db->mallocFailed || sqliteProcessJoin(pParse, p) ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2990 | return WRC_Abort; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2991 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2992 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2993 | /* For every "*" that occurs in the column list, insert the names of | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2994 | ** all columns in all tables. And for every TABLE.* insert the names | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2995 | ** of all columns in TABLE. The parser inserted a special expression | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2996 | ** with the TK_ALL operator for each "*" that it found in the column list. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2997 | ** The following code just has to locate the TK_ALL expressions and expand | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2998 | ** each one to the list of all columns in all tables. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 2999 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3000 | ** The first loop just checks to see if there are any "*" operators | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3001 | ** that need expanding. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3002 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3003 |   for(k=0; k<pEList->nExpr; k++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3004 | Expr *pE = pEList->a[k].pExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3005 | if( pE->op==TK_ALL ) break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3006 | if( pE->op==TK_DOT && pE->pRight && pE->pRight->op==TK_ALL | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3007 | && pE->pLeft && pE->pLeft->op==TK_ID ) break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3008 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3009 |   if( k<pEList->nExpr ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3010 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3011 | ** If we get here it means the result set contains one or more "*" | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3012 | ** operators that need to be expanded. Loop through each expression | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3013 | ** in the result set and expand them one by one. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3014 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3015 | struct ExprList_item *a = pEList->a; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3016 | ExprList *pNew = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3017 | int flags = pParse->db->flags; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3018 | int longNames = (flags & SQLITE_FullColNames)!=0 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3019 | && (flags & SQLITE_ShortColNames)==0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3020 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3021 |     for(k=0; k<pEList->nExpr; k++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3022 | Expr *pE = a[k].pExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3023 | if( pE->op!=TK_ALL && | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3024 |            (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3025 | /* This particular expression does not need to be expanded. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3026 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3027 | pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3028 |         if( pNew ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3029 | pNew->a[pNew->nExpr-1].zName = a[k].zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3030 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3031 | a[k].pExpr = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3032 | a[k].zName = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3033 |       }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3034 | /* This expression is a "*" or a "TABLE.*" and needs to be | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3035 | ** expanded. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3036 | int tableSeen = 0; /* Set to 1 when TABLE matches */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3037 | char *zTName; /* text of name of TABLE */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3038 |         if( pE->op==TK_DOT && pE->pLeft ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3039 | zTName = sqlite3NameFromToken(db, &pE->pLeft->token); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3040 |         }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3041 | zTName = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3042 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3043 |         for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3044 | Table *pTab = pFrom->pTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3045 | char *zTabName = pFrom->zAlias; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3046 |           if( zTabName==0 || zTabName[0]==0 ){ 
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3047 | zTabName = pTab->zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3048 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3049 | if( db->mallocFailed ) break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3050 |           if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3051 | continue; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3052 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3053 | tableSeen = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3054 |           for(j=0; j<pTab->nCol; j++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3055 | Expr *pExpr, *pRight; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3056 | char *zName = pTab->aCol[j].zName; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3057 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3058 | /* If a column is marked as 'hidden' (currently only possible | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3059 | ** for virtual tables), do not include it in the expanded | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3060 | ** result-set list. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3061 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3062 |             if( IsHiddenColumn(&pTab->aCol[j]) ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3063 | assert(IsVirtual(pTab)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3064 | continue; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3065 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3066 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3067 |             if( i>0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3068 | struct SrcList_item *pLeft = &pTabList->a[i-1]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3069 | if( (pLeft[1].jointype & JT_NATURAL)!=0 && | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3070 |                         columnIndex(pLeft->pTab, zName)>=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3071 | /* In a NATURAL join, omit the join columns from the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3072 | ** table on the right */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3073 | continue; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3074 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3075 |               if( sqlite3IdListIndex(pLeft[1].pUsing, zName)>=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3076 | /* In a join with a USING clause, omit columns in the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3077 | ** using clause from the table on the right. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3078 | continue; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3079 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3080 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3081 | pRight = sqlite3PExpr(pParse, TK_ID, 0, 0, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3082 | if( pRight==0 ) break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3083 | setQuotedToken(pParse, &pRight->token, zName); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3084 |             if( longNames || pTabList->nSrc>1 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3085 | Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3086 | pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3087 | if( pExpr==0 ) break; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3088 | setQuotedToken(pParse, &pLeft->token, zTabName); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3089 | setToken(&pExpr->span, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3090 | sqlite3MPrintf(db, "%s.%s", zTabName, zName)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3091 | pExpr->span.dyn = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3092 | pExpr->token.z = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3093 | pExpr->token.n = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3094 | pExpr->token.dyn = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3095 |             }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3096 | pExpr = pRight; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3097 | pExpr->span = pExpr->token; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3098 | pExpr->span.dyn = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3099 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3100 |             if( longNames ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3101 | pNew = sqlite3ExprListAppend(pParse, pNew, pExpr, &pExpr->span); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3102 |             }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3103 | pNew = sqlite3ExprListAppend(pParse, pNew, pExpr, &pRight->token); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3104 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3105 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3106 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3107 |         if( !tableSeen ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3108 |           if( zTName ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3109 | sqlite3ErrorMsg(pParse, "no such table: %s", zTName); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3110 |           }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3111 | sqlite3ErrorMsg(pParse, "no tables specified"); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3112 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3113 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3114 | sqlite3DbFree(db, zTName); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3115 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3116 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3117 | sqlite3ExprListDelete(db, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3118 | p->pEList = pNew; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3119 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3120 | #if SQLITE_MAX_COLUMN | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3121 |   if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3122 | sqlite3ErrorMsg(pParse, "too many columns in result set"); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3123 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3124 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3125 | return WRC_Continue; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3126 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3127 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3128 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3129 | ** No-op routine for the parse-tree walker. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3130 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3131 | ** When this routine is the Walker.xExprCallback then expression trees | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3132 | ** are walked without any actions being taken at each node. Presumably, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3133 | ** when this routine is used for Walker.xExprCallback then | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3134 | ** Walker.xSelectCallback is set to do something useful for every | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3135 | ** subquery in the parser tree. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3136 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3137 | static int exprWalkNoop(Walker *pWalker, Expr *pExpr){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3138 | return WRC_Continue; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3139 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3140 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3141 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3142 | ** This routine "expands" a SELECT statement and all of its subqueries. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3143 | ** For additional information on what it means to "expand" a SELECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3144 | ** statement, see the comment on the selectExpand worker callback above. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3145 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3146 | ** Expanding a SELECT statement is the first step in processing a | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3147 | ** SELECT statement. The SELECT statement must be expanded before | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3148 | ** name resolution is performed. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3149 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3150 | ** If anything goes wrong, an error message is written into pParse. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3151 | ** The calling function can detect the problem by looking at pParse->nErr | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3152 | ** and/or pParse->db->mallocFailed. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3153 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3154 | static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3155 | Walker w; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3156 | w.xSelectCallback = selectExpander; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3157 | w.xExprCallback = exprWalkNoop; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3158 | w.pParse = pParse; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3159 | sqlite3WalkSelect(&w, pSelect); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3160 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3161 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3162 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3163 | #ifndef SQLITE_OMIT_SUBQUERY | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3164 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3165 | ** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo() | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3166 | ** interface. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3167 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3168 | ** For each FROM-clause subquery, add Column.zType and Column.zColl | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3169 | ** information to the Table structure that represents the result set | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3170 | ** of that subquery. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3171 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3172 | ** The Table structure that represents the result set was constructed | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3173 | ** by selectExpander() but the type and collation information was omitted | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3174 | ** at that point because identifiers had not yet been resolved. This | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3175 | ** routine is called after identifier resolution. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3176 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3177 | static int selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3178 | Parse *pParse; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3179 | int i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3180 | SrcList *pTabList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3181 | struct SrcList_item *pFrom; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3182 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3183 | assert( p->selFlags & SF_Resolved ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3184 |   if( (p->selFlags & SF_HasTypeInfo)==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3185 | p->selFlags |= SF_HasTypeInfo; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3186 | pParse = pWalker->pParse; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3187 | pTabList = p->pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3188 |     for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3189 | Table *pTab = pFrom->pTab; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3190 |       if( pTab && (pTab->tabFlags & TF_Ephemeral)!=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3191 | /* A sub-query in the FROM clause of a SELECT */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3192 | Select *pSel = pFrom->pSelect; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3193 | assert( pSel ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3194 | while( pSel->pPrior ) pSel = pSel->pPrior; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3195 | selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSel); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3196 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3197 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3198 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3199 | return WRC_Continue; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3200 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3201 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3202 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3203 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3204 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3205 | ** This routine adds datatype and collating sequence information to | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3206 | ** the Table structures of all FROM-clause subqueries in a | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3207 | ** SELECT statement. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3208 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3209 | ** Use this routine after name resolution. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3210 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3211 | static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3212 | #ifndef SQLITE_OMIT_SUBQUERY | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3213 | Walker w; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3214 | w.xSelectCallback = selectAddSubqueryTypeInfo; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3215 | w.xExprCallback = exprWalkNoop; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3216 | w.pParse = pParse; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3217 | sqlite3WalkSelect(&w, pSelect); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3218 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3219 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3220 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3221 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3222 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3223 | ** This routine sets of a SELECT statement for processing. The | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3224 | ** following is accomplished: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3225 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3226 | ** * VDBE Cursor numbers are assigned to all FROM-clause terms. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3227 | ** * Ephemeral Table objects are created for all FROM-clause subqueries. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3228 | ** * ON and USING clauses are shifted into WHERE statements | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3229 | ** * Wildcards "*" and "TABLE.*" in result sets are expanded. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3230 | ** * Identifiers in expression are matched to tables. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3231 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3232 | ** This routine acts recursively on all subqueries within the SELECT. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3233 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3234 | void sqlite3SelectPrep( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3235 | Parse *pParse, /* The parser context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3236 | Select *p, /* The SELECT statement being coded. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3237 | NameContext *pOuterNC /* Name context for container */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3238 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3239 | sqlite3 *db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3240 | if( p==0 ) return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3241 | db = pParse->db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3242 | if( p->selFlags & SF_HasTypeInfo ) return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3243 | if( pParse->nErr || db->mallocFailed ) return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3244 | sqlite3SelectExpand(pParse, p); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3245 | if( pParse->nErr || db->mallocFailed ) return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3246 | sqlite3ResolveSelectNames(pParse, p, pOuterNC); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3247 | if( pParse->nErr || db->mallocFailed ) return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3248 | sqlite3SelectAddTypeInfo(pParse, p); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3249 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3250 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3251 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3252 | ** Reset the aggregate accumulator. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3253 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3254 | ** The aggregate accumulator is a set of memory cells that hold | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3255 | ** intermediate results while calculating an aggregate. This | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3256 | ** routine simply stores NULLs in all of those memory cells. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3257 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3258 | static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3259 | Vdbe *v = pParse->pVdbe; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3260 | int i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3261 | struct AggInfo_func *pFunc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3262 |   if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3263 | return; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3264 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3265 |   for(i=0; i<pAggInfo->nColumn; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3266 | sqlite3VdbeAddOp2(v, OP_Null, 0, pAggInfo->aCol[i].iMem); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3267 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3268 |   for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3269 | sqlite3VdbeAddOp2(v, OP_Null, 0, pFunc->iMem); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3270 |     if( pFunc->iDistinct>=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3271 | Expr *pE = pFunc->pExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3272 |       if( pE->pList==0 || pE->pList->nExpr!=1 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3273 | sqlite3ErrorMsg(pParse, "DISTINCT in aggregate must be followed " | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3274 | "by an expression"); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3275 | pFunc->iDistinct = -1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3276 |       }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3277 | KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->pList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3278 | sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3279 | (char*)pKeyInfo, P4_KEYINFO_HANDOFF); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3280 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3281 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3282 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3283 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3284 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3285 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3286 | ** Invoke the OP_AggFinalize opcode for every aggregate function | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3287 | ** in the AggInfo structure. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3288 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3289 | static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3290 | Vdbe *v = pParse->pVdbe; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3291 | int i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3292 | struct AggInfo_func *pF; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3293 |   for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3294 | ExprList *pList = pF->pExpr->pList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3295 | sqlite3VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3296 | (void*)pF->pFunc, P4_FUNCDEF); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3297 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3298 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3299 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3300 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3301 | ** Update the accumulator memory cells for an aggregate based on | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3302 | ** the current cursor position. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3303 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3304 | static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3305 | Vdbe *v = pParse->pVdbe; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3306 | int i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3307 | struct AggInfo_func *pF; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3308 | struct AggInfo_col *pC; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3309 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3310 | pAggInfo->directMode = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3311 |   for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3312 | int nArg; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3313 | int addrNext = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3314 | int regAgg; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3315 | ExprList *pList = pF->pExpr->pList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3316 |     if( pList ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3317 | nArg = pList->nExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3318 | regAgg = sqlite3GetTempRange(pParse, nArg); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3319 | sqlite3ExprCodeExprList(pParse, pList, regAgg, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3320 |     }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3321 | nArg = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3322 | regAgg = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3323 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3324 |     if( pF->iDistinct>=0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3325 | addrNext = sqlite3VdbeMakeLabel(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3326 | assert( nArg==1 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3327 | codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3328 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3329 |     if( pF->pFunc->needCollSeq ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3330 | CollSeq *pColl = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3331 | struct ExprList_item *pItem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3332 | int j; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3333 | assert( pList!=0 ); /* pList!=0 if pF->pFunc->needCollSeq is true */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3334 |       for(j=0, pItem=pList->a; !pColl && j<nArg; j++, pItem++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3335 | pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3336 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3337 |       if( !pColl ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3338 | pColl = pParse->db->pDfltColl; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3339 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3340 | sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3341 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3342 | sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3343 | (void*)pF->pFunc, P4_FUNCDEF); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3344 | sqlite3VdbeChangeP5(v, nArg); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3345 | sqlite3ReleaseTempRange(pParse, regAgg, nArg); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3346 | sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3347 |     if( addrNext ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3348 | sqlite3VdbeResolveLabel(v, addrNext); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3349 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3350 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3351 |   for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3352 | sqlite3ExprCode(pParse, pC->pExpr, pC->iMem); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3353 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3354 | pAggInfo->directMode = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3355 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3356 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3357 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3358 | ** Generate code for the SELECT statement given in the p argument. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3359 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3360 | ** The results are distributed in various ways depending on the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3361 | ** contents of the SelectDest structure pointed to by argument pDest | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3362 | ** as follows: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3363 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3364 | ** pDest->eDest Result | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3365 | ** ------------ ------------------------------------------- | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3366 | ** SRT_Output Generate a row of output (using the OP_ResultRow | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3367 | ** opcode) for each row in the result set. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3368 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3369 | ** SRT_Mem Only valid if the result is a single column. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3370 | ** Store the first column of the first result row | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3371 | ** in register pDest->iParm then abandon the rest | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3372 | ** of the query. This destination implies "LIMIT 1". | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3373 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3374 | ** SRT_Set The result must be a single column. Store each | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3375 | ** row of result as the key in table pDest->iParm. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3376 | ** Apply the affinity pDest->affinity before storing | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3377 | ** results. Used to implement "IN (SELECT ...)". | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3378 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3379 | ** SRT_Union Store results as a key in a temporary table pDest->iParm. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3380 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3381 | ** SRT_Except Remove results from the temporary table pDest->iParm. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3382 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3383 | ** SRT_Table Store results in temporary table pDest->iParm. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3384 | ** This is like SRT_EphemTab except that the table | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3385 | ** is assumed to already be open. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3386 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3387 | ** SRT_EphemTab Create an temporary table pDest->iParm and store | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3388 | ** the result there. The cursor is left open after | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3389 | ** returning. This is like SRT_Table except that | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3390 | ** this destination uses OP_OpenEphemeral to create | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3391 | ** the table first. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3392 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3393 | ** SRT_Coroutine Generate a co-routine that returns a new row of | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3394 | ** results each time it is invoked. The entry point | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3395 | ** of the co-routine is stored in register pDest->iParm. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3396 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3397 | ** SRT_Exists Store a 1 in memory cell pDest->iParm if the result | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3398 | ** set is not empty. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3399 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3400 | ** SRT_Discard Throw the results away. This is used by SELECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3401 | ** statements within triggers whose only purpose is | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3402 | ** the side-effects of functions. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3403 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3404 | ** This routine returns the number of errors. If any errors are | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3405 | ** encountered, then an appropriate error message is left in | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3406 | ** pParse->zErrMsg. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3407 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3408 | ** This routine does NOT free the Select structure passed in. The | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3409 | ** calling function needs to do that. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3410 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3411 | int sqlite3Select( | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3412 | Parse *pParse, /* The parser context */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3413 | Select *p, /* The SELECT statement being coded. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3414 | SelectDest *pDest /* What to do with the query results */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3415 | ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3416 | int i, j; /* Loop counters */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3417 | WhereInfo *pWInfo; /* Return from sqlite3WhereBegin() */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3418 | Vdbe *v; /* The virtual machine under construction */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3419 | int isAgg; /* True for select lists like "count(*)" */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3420 | ExprList *pEList; /* List of columns to extract. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3421 | SrcList *pTabList; /* List of tables to select from */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3422 | Expr *pWhere; /* The WHERE clause. May be NULL */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3423 | ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3424 | ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3425 | Expr *pHaving; /* The HAVING clause. May be NULL */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3426 | int isDistinct; /* True if the DISTINCT keyword is present */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3427 | int distinct; /* Table to use for the distinct set */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3428 | int rc = 1; /* Value to return from this function */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3429 | int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3430 | AggInfo sAggInfo; /* Information used by aggregate queries */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3431 | int iEnd; /* Address of the end of the query */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3432 | sqlite3 *db; /* The database connection */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3433 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3434 | db = pParse->db; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3435 |   if( p==0 || db->mallocFailed || pParse->nErr ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3436 | return 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3437 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3438 | if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3439 | memset(&sAggInfo, 0, sizeof(sAggInfo)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3440 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3441 | pOrderBy = p->pOrderBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3442 |   if( IgnorableOrderby(pDest) ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3443 | p->pOrderBy = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3444 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3445 | /* In these cases the DISTINCT operator makes no difference to the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3446 | ** results, so remove it if it were specified. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3447 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3448 | assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3449 | pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3450 | p->selFlags &= ~SF_Distinct; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3451 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3452 | sqlite3SelectPrep(pParse, p, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3453 |   if( pParse->nErr ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3454 | goto select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3455 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3456 | p->pOrderBy = pOrderBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3457 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3458 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3459 | /* Make local copies of the parameters for this query. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3460 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3461 | pTabList = p->pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3462 | isAgg = (p->selFlags & SF_Aggregate)!=0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3463 | pEList = p->pEList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3464 | if( pEList==0 ) goto select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3465 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3466 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3467 | ** Do not even attempt to generate any code if we have already seen | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3468 | ** errors before this routine starts. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3469 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3470 | if( pParse->nErr>0 ) goto select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3471 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3472 | /* ORDER BY is ignored for some destinations. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3473 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3474 |   if( IgnorableOrderby(pDest) ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3475 | pOrderBy = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3476 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3477 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3478 | /* Begin generating code. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3479 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3480 | v = sqlite3GetVdbe(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3481 | if( v==0 ) goto select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3482 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3483 | /* Generate code for all sub-queries in the FROM clause | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3484 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3485 | #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3486 |   for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3487 | struct SrcList_item *pItem = &pTabList->a[i]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3488 | SelectDest dest; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3489 | Select *pSub = pItem->pSelect; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3490 | int isAggSub; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3491 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3492 | if( pSub==0 || pItem->isPopulated ) continue; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3493 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3494 | /* Increment Parse.nHeight by the height of the largest expression | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3495 | ** tree refered to by this, the parent select. The child select | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3496 | ** may contain expression trees of at most | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3497 | ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3498 | ** more conservative than necessary, but much easier than enforcing | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3499 | ** an exact limit. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3500 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3501 | pParse->nHeight += sqlite3SelectExprHeight(p); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3502 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3503 | /* Check to see if the subquery can be absorbed into the parent. */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3504 | isAggSub = (pSub->selFlags & SF_Aggregate)!=0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3505 |     if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3506 |       if( isAggSub ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3507 | isAgg = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3508 | p->selFlags |= SF_Aggregate; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3509 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3510 | i = -1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3511 |     }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3512 | sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3513 | assert( pItem->isPopulated==0 ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3514 | sqlite3Select(pParse, pSub, &dest); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3515 | pItem->isPopulated = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3516 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3517 |     if( pParse->nErr || db->mallocFailed ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3518 | goto select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3519 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3520 | pParse->nHeight -= sqlite3SelectExprHeight(p); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3521 | pTabList = p->pSrc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3522 |     if( !IgnorableOrderby(pDest) ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3523 | pOrderBy = p->pOrderBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3524 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3525 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3526 | pEList = p->pEList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3527 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3528 | pWhere = p->pWhere; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3529 | pGroupBy = p->pGroupBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3530 | pHaving = p->pHaving; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3531 | isDistinct = (p->selFlags & SF_Distinct)!=0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3532 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3533 | #ifndef SQLITE_OMIT_COMPOUND_SELECT | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3534 | /* If there is are a sequence of queries, do the earlier ones first. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3535 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3536 |   if( p->pPrior ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3537 |     if( p->pRightmost==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3538 | Select *pLoop, *pRight = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3539 | int cnt = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3540 | int mxSelect; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3541 |       for(pLoop=p; pLoop; pLoop=pLoop->pPrior, cnt++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3542 | pLoop->pRightmost = p; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3543 | pLoop->pNext = pRight; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3544 | pRight = pLoop; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3545 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3546 | mxSelect = db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3547 |       if( mxSelect && cnt>mxSelect ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3548 | sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3549 | return 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3550 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3551 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3552 | return multiSelect(pParse, p, pDest); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3553 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3554 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3555 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3556 | /* If writing to memory or generating a set | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3557 | ** only a single column may be output. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3558 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3559 | #ifndef SQLITE_OMIT_SUBQUERY | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3560 |   if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3561 | goto select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3562 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3563 | #endif | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3564 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3565 | /* If possible, rewrite the query to use GROUP BY instead of DISTINCT. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3566 | ** GROUP BY might use an index, DISTINCT never does. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3567 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3568 |   if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct && !p->pGroupBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3569 | p->pGroupBy = sqlite3ExprListDup(db, p->pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3570 | pGroupBy = p->pGroupBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3571 | p->selFlags &= ~SF_Distinct; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3572 | isDistinct = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3573 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3574 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3575 | /* If there is an ORDER BY clause, then this sorting | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3576 | ** index might end up being unused if the data can be | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3577 | ** extracted in pre-sorted order. If that is the case, then the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3578 | ** OP_OpenEphemeral instruction will be changed to an OP_Noop once | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3579 | ** we figure out that the sorting index is not needed. The addrSortIndex | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3580 | ** variable is used to facilitate that change. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3581 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3582 |   if( pOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3583 | KeyInfo *pKeyInfo; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3584 | pKeyInfo = keyInfoFromExprList(pParse, pOrderBy); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3585 | pOrderBy->iECursor = pParse->nTab++; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3586 | p->addrOpenEphm[2] = addrSortIndex = | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3587 | sqlite3VdbeAddOp4(v, OP_OpenEphemeral, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3588 | pOrderBy->iECursor, pOrderBy->nExpr+2, 0, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3589 | (char*)pKeyInfo, P4_KEYINFO_HANDOFF); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3590 |   }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3591 | addrSortIndex = -1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3592 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3593 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3594 | /* If the output is destined for a temporary table, open that table. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3595 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3596 |   if( pDest->eDest==SRT_EphemTab ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3597 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iParm, pEList->nExpr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3598 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3599 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3600 | /* Set the limiter. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3601 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3602 | iEnd = sqlite3VdbeMakeLabel(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3603 | computeLimitRegisters(pParse, p, iEnd); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3604 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3605 | /* Open a virtual index to use for the distinct set. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3606 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3607 |   if( isDistinct ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3608 | KeyInfo *pKeyInfo; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3609 | assert( isAgg || pGroupBy ); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3610 | distinct = pParse->nTab++; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3611 | pKeyInfo = keyInfoFromExprList(pParse, p->pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3612 | sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3613 | (char*)pKeyInfo, P4_KEYINFO_HANDOFF); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3614 |   }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3615 | distinct = -1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3616 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3617 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3618 | /* Aggregate and non-aggregate queries are handled differently */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3619 |   if( !isAgg && pGroupBy==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3620 | /* This case is for non-aggregate queries | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3621 | ** Begin the database scan | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3622 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3623 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3624 | if( pWInfo==0 ) goto select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3625 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3626 | /* If sorting index that was created by a prior OP_OpenEphemeral | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3627 | ** instruction ended up not being needed, then change the OP_OpenEphemeral | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3628 | ** into an OP_Noop. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3629 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3630 |     if( addrSortIndex>=0 && pOrderBy==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3631 | sqlite3VdbeChangeToNoop(v, addrSortIndex, 1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3632 | p->addrOpenEphm[2] = -1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3633 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3634 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3635 | /* Use the standard inner loop | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3636 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3637 | assert(!isDistinct); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3638 | selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, -1, pDest, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3639 | pWInfo->iContinue, pWInfo->iBreak); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3640 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3641 | /* End the database scan loop. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3642 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3643 | sqlite3WhereEnd(pWInfo); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3644 |   }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3645 | /* This is the processing for aggregate queries */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3646 | NameContext sNC; /* Name context for processing aggregate information */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3647 | int iAMem; /* First Mem address for storing current GROUP BY */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3648 | int iBMem; /* First Mem address for previous GROUP BY */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3649 | int iUseFlag; /* Mem address holding flag indicating that at least | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3650 | ** one row of the input to the aggregator has been | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3651 | ** processed */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3652 | int iAbortFlag; /* Mem address which causes query abort if positive */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3653 | int groupBySort; /* Rows come from source in GROUP BY order */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3654 | int addrEnd; /* End of processing for this SELECT */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3655 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3656 | /* Remove any and all aliases between the result set and the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3657 | ** GROUP BY clause. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3658 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3659 |     if( pGroupBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3660 | int i; /* Loop counter */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3661 | struct ExprList_item *pItem; /* For looping over expression in a list */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3662 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3663 |       for(i=p->pEList->nExpr, pItem=p->pEList->a; i>0; i--, pItem++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3664 | pItem->iAlias = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3665 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3666 |       for(i=pGroupBy->nExpr, pItem=pGroupBy->a; i>0; i--, pItem++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3667 | pItem->iAlias = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3668 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3669 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3670 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3671 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3672 | /* Create a label to jump to when we want to abort the query */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3673 | addrEnd = sqlite3VdbeMakeLabel(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3674 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3675 | /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3676 | ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3677 | ** SELECT statement. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3678 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3679 | memset(&sNC, 0, sizeof(sNC)); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3680 | sNC.pParse = pParse; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3681 | sNC.pSrcList = pTabList; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3682 | sNC.pAggInfo = &sAggInfo; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3683 | sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3684 | sAggInfo.pGroupBy = pGroupBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3685 | sqlite3ExprAnalyzeAggList(&sNC, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3686 | sqlite3ExprAnalyzeAggList(&sNC, pOrderBy); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3687 |     if( pHaving ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3688 | sqlite3ExprAnalyzeAggregates(&sNC, pHaving); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3689 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3690 | sAggInfo.nAccumulator = sAggInfo.nColumn; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3691 |     for(i=0; i<sAggInfo.nFunc; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3692 | sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3693 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3694 | if( db->mallocFailed ) goto select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3695 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3696 | /* Processing for aggregates with GROUP BY is very different and | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3697 | ** much more complex than aggregates without a GROUP BY. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3698 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3699 |     if( pGroupBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3700 | KeyInfo *pKeyInfo; /* Keying information for the group by clause */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3701 | int j1; /* A-vs-B comparision jump */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3702 | int addrOutputRow; /* Start of subroutine that outputs a result row */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3703 | int regOutputRow; /* Return address register for output subroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3704 | int addrSetAbort; /* Set the abort flag and return */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3705 | int addrTopOfLoop; /* Top of the input loop */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3706 | int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3707 | int addrReset; /* Subroutine for resetting the accumulator */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3708 | int regReset; /* Return address register for reset subroutine */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3709 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3710 | /* If there is a GROUP BY clause we might need a sorting index to | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3711 | ** implement it. Allocate that sorting index now. If it turns out | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3712 | ** that we do not need it after all, the OpenEphemeral instruction | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3713 | ** will be converted into a Noop. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3714 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3715 | sAggInfo.sortingIdx = pParse->nTab++; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3716 | pKeyInfo = keyInfoFromExprList(pParse, pGroupBy); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3717 | addrSortingIdx = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3718 | sAggInfo.sortingIdx, sAggInfo.nSortingColumn, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3719 | 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3720 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3721 | /* Initialize memory locations used by GROUP BY aggregate processing | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3722 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3723 | iUseFlag = ++pParse->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3724 | iAbortFlag = ++pParse->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3725 | regOutputRow = ++pParse->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3726 | addrOutputRow = sqlite3VdbeMakeLabel(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3727 | regReset = ++pParse->nMem; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3728 | addrReset = sqlite3VdbeMakeLabel(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3729 | iAMem = pParse->nMem + 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3730 | pParse->nMem += pGroupBy->nExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3731 | iBMem = pParse->nMem + 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3732 | pParse->nMem += pGroupBy->nExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3733 | sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3734 | VdbeComment((v, "clear abort flag")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3735 | sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3736 | VdbeComment((v, "indicate accumulator empty")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3737 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3738 | /* Begin a loop that will extract all source rows in GROUP BY order. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3739 | ** This might involve two separate loops with an OP_Sort in between, or | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3740 | ** it might be a single loop that uses an index to extract information | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3741 | ** in the right order to begin with. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3742 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3743 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3744 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3745 | if( pWInfo==0 ) goto select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3746 |       if( pGroupBy==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3747 | /* The optimizer is able to deliver rows in group by order so | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3748 | ** we do not have to sort. The OP_OpenEphemeral table will be | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3749 | ** cancelled later because we still need to use the pKeyInfo | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3750 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3751 | pGroupBy = p->pGroupBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3752 | groupBySort = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3753 |       }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3754 | /* Rows are coming out in undetermined order. We have to push | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3755 | ** each row into a sorting index, terminate the first loop, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3756 | ** then loop over the sorting index in order to get the output | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3757 | ** in sorted order | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3758 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3759 | int regBase; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3760 | int regRecord; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3761 | int nCol; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3762 | int nGroupBy; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3763 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3764 | groupBySort = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3765 | nGroupBy = pGroupBy->nExpr; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3766 | nCol = nGroupBy + 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3767 | j = nGroupBy+1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3768 |         for(i=0; i<sAggInfo.nColumn; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3769 |           if( sAggInfo.aCol[i].iSorterColumn>=j ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3770 | nCol++; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3771 | j++; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3772 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3773 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3774 | regBase = sqlite3GetTempRange(pParse, nCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3775 | sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3776 | sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3777 | j = nGroupBy+1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3778 |         for(i=0; i<sAggInfo.nColumn; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3779 | struct AggInfo_col *pCol = &sAggInfo.aCol[i]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3780 |           if( pCol->iSorterColumn>=j ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3781 | int r1 = j + regBase; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3782 | int r2; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3783 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3784 | r2 = sqlite3ExprCodeGetColumn(pParse, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3785 | pCol->pTab, pCol->iColumn, pCol->iTable, r1, 0); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3786 |             if( r1!=r2 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3787 | sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3788 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3789 | j++; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3790 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3791 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3792 | regRecord = sqlite3GetTempReg(pParse); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3793 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3794 | sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, regRecord); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3795 | sqlite3ReleaseTempReg(pParse, regRecord); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3796 | sqlite3ReleaseTempRange(pParse, regBase, nCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3797 | sqlite3WhereEnd(pWInfo); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3798 | sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3799 | VdbeComment((v, "GROUP BY sort")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3800 | sAggInfo.useSortingIdx = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3801 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3802 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3803 | /* Evaluate the current GROUP BY terms and store in b0, b1, b2... | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3804 | ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3805 | ** Then compare the current GROUP BY terms against the GROUP BY terms | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3806 | ** from the previous row currently stored in a0, a1, a2... | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3807 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3808 | addrTopOfLoop = sqlite3VdbeCurrentAddr(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3809 |       for(j=0; j<pGroupBy->nExpr; j++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3810 |         if( groupBySort ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3811 | sqlite3VdbeAddOp3(v, OP_Column, sAggInfo.sortingIdx, j, iBMem+j); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3812 |         }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3813 | sAggInfo.directMode = 1; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3814 | sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3815 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3816 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3817 | sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3818 | (char*)pKeyInfo, P4_KEYINFO); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3819 | j1 = sqlite3VdbeCurrentAddr(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3820 | sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3821 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3822 | /* Generate code that runs whenever the GROUP BY changes. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3823 | ** Changes in the GROUP BY are detected by the previous code | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3824 | ** block. If there were no changes, this block is skipped. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3825 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3826 | ** This code copies current group by terms in b0,b1,b2,... | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3827 | ** over to a0,a1,a2. It then calls the output subroutine | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3828 | ** and resets the aggregate accumulator registers in preparation | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3829 | ** for the next GROUP BY batch. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3830 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3831 | sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3832 | sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3833 | VdbeComment((v, "output one row")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3834 | sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3835 | VdbeComment((v, "check abort flag")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3836 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3837 | VdbeComment((v, "reset accumulator")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3838 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3839 | /* Update the aggregate accumulators based on the content of | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3840 | ** the current row | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3841 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3842 | sqlite3VdbeJumpHere(v, j1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3843 | updateAccumulator(pParse, &sAggInfo); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3844 | sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3845 | VdbeComment((v, "indicate data in accumulator")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3846 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3847 | /* End of the loop | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3848 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3849 |       if( groupBySort ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3850 | sqlite3VdbeAddOp2(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3851 |       }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3852 | sqlite3WhereEnd(pWInfo); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3853 | sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3854 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3855 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3856 | /* Output the final row of result | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3857 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3858 | sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3859 | VdbeComment((v, "output final row")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3860 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3861 | /* Jump over the subroutines | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3862 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3863 | sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEnd); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3864 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3865 | /* Generate a subroutine that outputs a single row of the result | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3866 | ** set. This subroutine first looks at the iUseFlag. If iUseFlag | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3867 | ** is less than or equal to zero, the subroutine is a no-op. If | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3868 | ** the processing calls for the query to abort, this subroutine | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3869 | ** increments the iAbortFlag memory location before returning in | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3870 | ** order to signal the caller to abort. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3871 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3872 | addrSetAbort = sqlite3VdbeCurrentAddr(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3873 | sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3874 | VdbeComment((v, "set abort flag")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3875 | sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3876 | sqlite3VdbeResolveLabel(v, addrOutputRow); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3877 | addrOutputRow = sqlite3VdbeCurrentAddr(v); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3878 | sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3879 | VdbeComment((v, "Groupby result generator entry point")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3880 | sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3881 | finalizeAggFunctions(pParse, &sAggInfo); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3882 |       if( pHaving ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3883 | sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3884 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3885 | selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3886 | distinct, pDest, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3887 | addrOutputRow+1, addrSetAbort); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3888 | sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3889 | VdbeComment((v, "end groupby result generator")); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3890 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3891 | /* Generate a subroutine that will reset the group-by accumulator | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3892 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3893 | sqlite3VdbeResolveLabel(v, addrReset); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3894 | resetAccumulator(pParse, &sAggInfo); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3895 | sqlite3VdbeAddOp1(v, OP_Return, regReset); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3896 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3897 | } /* endif pGroupBy */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3898 |     else {
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3899 | ExprList *pMinMax = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3900 | ExprList *pDel = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3901 | u8 flag; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3902 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3903 | /* Check if the query is of one of the following forms: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3904 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3905 | ** SELECT min(x) FROM ... | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3906 | ** SELECT max(x) FROM ... | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3907 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3908 | ** If it is, then ask the code in where.c to attempt to sort results | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3909 | ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3910 | ** If where.c is able to produce results sorted in this order, then | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3911 | ** add vdbe code to break out of the processing loop after the | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3912 | ** first iteration (since the first iteration of the loop is | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3913 | ** guaranteed to operate on the row with the minimum or maximum | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3914 | ** value of x, the only row required). | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3915 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3916 | ** A special flag must be passed to sqlite3WhereBegin() to slightly | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3917 | ** modify behaviour as follows: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3918 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3919 | ** + If the query is a "SELECT min(x)", then the loop coded by | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3920 | ** where.c should not iterate over any values with a NULL value | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3921 | ** for x. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3922 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3923 | ** + The optimizer code in where.c (the thing that decides which | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3924 | ** index or indices to use) should place a different priority on | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3925 | ** satisfying the 'ORDER BY' clause than it does in other cases. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3926 | ** Refer to code and comments in where.c for details. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3927 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3928 | flag = minMaxQuery(pParse, p); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3929 |       if( flag ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3930 | pDel = pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->pList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3931 |         if( pMinMax && !db->mallocFailed ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3932 | pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3933 | pMinMax->a[0].pExpr->op = TK_COLUMN; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3934 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3935 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3936 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3937 | /* This case runs if the aggregate has no GROUP BY clause. The | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3938 | ** processing is much simpler since there is only a single row | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3939 | ** of output. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3940 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3941 | resetAccumulator(pParse, &sAggInfo); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3942 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, flag); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3943 |       if( pWInfo==0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3944 | sqlite3ExprListDelete(db, pDel); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3945 | goto select_end; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3946 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3947 | updateAccumulator(pParse, &sAggInfo); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3948 |       if( !pMinMax && flag ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3949 | sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3950 | VdbeComment((v, "%s() by index",(flag==WHERE_ORDERBY_MIN?"min":"max"))); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3951 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3952 | sqlite3WhereEnd(pWInfo); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3953 | finalizeAggFunctions(pParse, &sAggInfo); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3954 | pOrderBy = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3955 |       if( pHaving ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3956 | sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3957 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3958 | selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1, | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3959 | pDest, addrEnd, addrEnd); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3960 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3961 | sqlite3ExprListDelete(db, pDel); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3962 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3963 | sqlite3VdbeResolveLabel(v, addrEnd); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3964 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3965 | } /* endif aggregate query */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3966 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3967 | /* If there is an ORDER BY clause, then we need to sort the results | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3968 | ** and send them to the callback one by one. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3969 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3970 |   if( pOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3971 | generateSortTail(pParse, p, v, pEList->nExpr, pDest); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3972 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3973 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3974 | /* Jump here to skip this query | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3975 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3976 | sqlite3VdbeResolveLabel(v, iEnd); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3977 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3978 | /* The SELECT was successfully coded. Set the return code to 0 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3979 | ** to indicate no errors. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3980 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3981 | rc = 0; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3982 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3983 | /* Control jumps to here if an error is encountered above, or upon | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3984 | ** successful coding of the SELECT. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3985 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3986 | select_end: | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3987 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3988 | /* Identify column names if results of the SELECT are to be output. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3989 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3990 |   if( rc==SQLITE_OK && pDest->eDest==SRT_Output ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3991 | generateColumnNames(pParse, pTabList, pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3992 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3993 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3994 | sqlite3DbFree(db, sAggInfo.aCol); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3995 | sqlite3DbFree(db, sAggInfo.aFunc); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3996 | return rc; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3997 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3998 | |
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 3999 | #if defined(SQLITE_DEBUG) | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4000 | /* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4001 | ******************************************************************************* | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4002 | ** The following code is used for testing and debugging only. The code | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4003 | ** that follows does not appear in normal builds. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4004 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4005 | ** These routines are used to print out the content of all or part of a | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4006 | ** parse structures such as Select or Expr. Such printouts are useful | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4007 | ** for helping to understand what is happening inside the code generator | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4008 | ** during the execution of complex SELECT statements. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4009 | ** | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4010 | ** These routine are not called anywhere from within the normal | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4011 | ** code base. Then are intended to be called from within the debugger | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4012 | ** or from temporary "printf" statements inserted for debugging. | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4013 | */ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4014 | void sqlite3PrintExpr(Expr *p){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4015 |   if( p->token.z && p->token.n>0 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4016 |     sqlite3DebugPrintf("(%.*s", p->token.n, p->token.z);
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4017 |   }else{
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4018 |     sqlite3DebugPrintf("(%d", p->op);
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4019 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4020 |   if( p->pLeft ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4021 |     sqlite3DebugPrintf(" ");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4022 | sqlite3PrintExpr(p->pLeft); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4023 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4024 |   if( p->pRight ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4025 |     sqlite3DebugPrintf(" ");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4026 | sqlite3PrintExpr(p->pRight); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4027 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4028 |   sqlite3DebugPrintf(")");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4029 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4030 | void sqlite3PrintExprList(ExprList *pList){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4031 | int i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4032 |   for(i=0; i<pList->nExpr; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4033 | sqlite3PrintExpr(pList->a[i].pExpr); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4034 |     if( i<pList->nExpr-1 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4035 |       sqlite3DebugPrintf(", ");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4036 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4037 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4038 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4039 | void sqlite3PrintSelect(Select *p, int indent){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4040 |   sqlite3DebugPrintf("%*sSELECT(%p) ", indent, "", p);
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4041 | sqlite3PrintExprList(p->pEList); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4042 |   sqlite3DebugPrintf("\n");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4043 |   if( p->pSrc ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4044 | char *zPrefix; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4045 | int i; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4046 | zPrefix = "FROM"; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4047 |     for(i=0; i<p->pSrc->nSrc; i++){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4048 | struct SrcList_item *pItem = &p->pSrc->a[i]; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4049 |       sqlite3DebugPrintf("%*s ", indent+6, zPrefix);
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4050 | zPrefix = ""; | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4051 |       if( pItem->pSelect ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4052 |         sqlite3DebugPrintf("(\n");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4053 | sqlite3PrintSelect(pItem->pSelect, indent+10); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4054 |         sqlite3DebugPrintf("%*s)", indent+8, "");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4055 |       }else if( pItem->zName ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4056 |         sqlite3DebugPrintf("%s", pItem->zName);
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4057 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4058 |       if( pItem->pTab ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4059 |         sqlite3DebugPrintf("(table: %s)", pItem->pTab->zName);
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4060 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4061 |       if( pItem->zAlias ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4062 |         sqlite3DebugPrintf(" AS %s", pItem->zAlias);
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4063 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4064 |       if( i<p->pSrc->nSrc-1 ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4065 |         sqlite3DebugPrintf(",");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4066 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4067 |       sqlite3DebugPrintf("\n");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4068 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4069 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4070 |   if( p->pWhere ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4071 |     sqlite3DebugPrintf("%*s WHERE ", indent, "");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4072 | sqlite3PrintExpr(p->pWhere); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4073 |     sqlite3DebugPrintf("\n");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4074 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4075 |   if( p->pGroupBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4076 |     sqlite3DebugPrintf("%*s GROUP BY ", indent, "");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4077 | sqlite3PrintExprList(p->pGroupBy); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4078 |     sqlite3DebugPrintf("\n");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4079 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4080 |   if( p->pHaving ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4081 |     sqlite3DebugPrintf("%*s HAVING ", indent, "");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4082 | sqlite3PrintExpr(p->pHaving); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4083 |     sqlite3DebugPrintf("\n");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4084 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4085 |   if( p->pOrderBy ){
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4086 |     sqlite3DebugPrintf("%*s ORDER BY ", indent, "");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4087 | sqlite3PrintExprList(p->pOrderBy); | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4088 |     sqlite3DebugPrintf("\n");
 | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4089 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4090 | } | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4091 | /* End of the structure debug printing code | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4092 | *****************************************************************************/ | 
| 
08ec8eefde2f
Revision: 201003
 Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> parents: diff
changeset | 4093 | #endif /* defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */ |