xref: /illumos-gate/usr/src/lib/libsqlite/src/expr.c (revision 55fea89d)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate ** 2001 September 15
37c478bd9Sstevel@tonic-gate **
47c478bd9Sstevel@tonic-gate ** The author disclaims copyright to this source code.  In place of
57c478bd9Sstevel@tonic-gate ** a legal notice, here is a blessing:
67c478bd9Sstevel@tonic-gate **
77c478bd9Sstevel@tonic-gate **    May you do good and not evil.
87c478bd9Sstevel@tonic-gate **    May you find forgiveness for yourself and forgive others.
97c478bd9Sstevel@tonic-gate **    May you share freely, never taking more than you give.
107c478bd9Sstevel@tonic-gate **
117c478bd9Sstevel@tonic-gate *************************************************************************
127c478bd9Sstevel@tonic-gate ** This file contains routines used for analyzing expressions and
137c478bd9Sstevel@tonic-gate ** for generating VDBE code that evaluates expressions in SQLite.
147c478bd9Sstevel@tonic-gate **
157c478bd9Sstevel@tonic-gate ** $Id: expr.c,v 1.114.2.3 2004/07/22 17:10:10 drh Exp $
167c478bd9Sstevel@tonic-gate */
177c478bd9Sstevel@tonic-gate #include "sqliteInt.h"
187c478bd9Sstevel@tonic-gate #include <ctype.h>
197c478bd9Sstevel@tonic-gate 
207c478bd9Sstevel@tonic-gate /*
217c478bd9Sstevel@tonic-gate ** Construct a new expression node and return a pointer to it.  Memory
227c478bd9Sstevel@tonic-gate ** for this node is obtained from sqliteMalloc().  The calling function
237c478bd9Sstevel@tonic-gate ** is responsible for making sure the node eventually gets freed.
247c478bd9Sstevel@tonic-gate */
sqliteExpr(int op,Expr * pLeft,Expr * pRight,Token * pToken)257c478bd9Sstevel@tonic-gate Expr *sqliteExpr(int op, Expr *pLeft, Expr *pRight, Token *pToken){
267c478bd9Sstevel@tonic-gate   Expr *pNew;
277c478bd9Sstevel@tonic-gate   pNew = sqliteMalloc( sizeof(Expr) );
287c478bd9Sstevel@tonic-gate   if( pNew==0 ){
297c478bd9Sstevel@tonic-gate     /* When malloc fails, we leak memory from pLeft and pRight */
307c478bd9Sstevel@tonic-gate     return 0;
317c478bd9Sstevel@tonic-gate   }
327c478bd9Sstevel@tonic-gate   pNew->op = op;
337c478bd9Sstevel@tonic-gate   pNew->pLeft = pLeft;
347c478bd9Sstevel@tonic-gate   pNew->pRight = pRight;
357c478bd9Sstevel@tonic-gate   if( pToken ){
367c478bd9Sstevel@tonic-gate     assert( pToken->dyn==0 );
377c478bd9Sstevel@tonic-gate     pNew->token = *pToken;
387c478bd9Sstevel@tonic-gate     pNew->span = *pToken;
397c478bd9Sstevel@tonic-gate   }else{
407c478bd9Sstevel@tonic-gate     assert( pNew->token.dyn==0 );
417c478bd9Sstevel@tonic-gate     assert( pNew->token.z==0 );
427c478bd9Sstevel@tonic-gate     assert( pNew->token.n==0 );
437c478bd9Sstevel@tonic-gate     if( pLeft && pRight ){
447c478bd9Sstevel@tonic-gate       sqliteExprSpan(pNew, &pLeft->span, &pRight->span);
457c478bd9Sstevel@tonic-gate     }else{
467c478bd9Sstevel@tonic-gate       pNew->span = pNew->token;
477c478bd9Sstevel@tonic-gate     }
487c478bd9Sstevel@tonic-gate   }
497c478bd9Sstevel@tonic-gate   return pNew;
507c478bd9Sstevel@tonic-gate }
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate /*
537c478bd9Sstevel@tonic-gate ** Set the Expr.span field of the given expression to span all
547c478bd9Sstevel@tonic-gate ** text between the two given tokens.
557c478bd9Sstevel@tonic-gate */
sqliteExprSpan(Expr * pExpr,Token * pLeft,Token * pRight)567c478bd9Sstevel@tonic-gate void sqliteExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
577c478bd9Sstevel@tonic-gate   assert( pRight!=0 );
587c478bd9Sstevel@tonic-gate   assert( pLeft!=0 );
597c478bd9Sstevel@tonic-gate   /* Note: pExpr might be NULL due to a prior malloc failure */
607c478bd9Sstevel@tonic-gate   if( pExpr && pRight->z && pLeft->z ){
617c478bd9Sstevel@tonic-gate     if( pLeft->dyn==0 && pRight->dyn==0 ){
627c478bd9Sstevel@tonic-gate       pExpr->span.z = pLeft->z;
637c478bd9Sstevel@tonic-gate       pExpr->span.n = pRight->n + Addr(pRight->z) - Addr(pLeft->z);
647c478bd9Sstevel@tonic-gate     }else{
657c478bd9Sstevel@tonic-gate       pExpr->span.z = 0;
667c478bd9Sstevel@tonic-gate     }
677c478bd9Sstevel@tonic-gate   }
687c478bd9Sstevel@tonic-gate }
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate /*
717c478bd9Sstevel@tonic-gate ** Construct a new expression node for a function with multiple
727c478bd9Sstevel@tonic-gate ** arguments.
737c478bd9Sstevel@tonic-gate */
sqliteExprFunction(ExprList * pList,Token * pToken)747c478bd9Sstevel@tonic-gate Expr *sqliteExprFunction(ExprList *pList, Token *pToken){
757c478bd9Sstevel@tonic-gate   Expr *pNew;
767c478bd9Sstevel@tonic-gate   pNew = sqliteMalloc( sizeof(Expr) );
777c478bd9Sstevel@tonic-gate   if( pNew==0 ){
787c478bd9Sstevel@tonic-gate     /* sqliteExprListDelete(pList); // Leak pList when malloc fails */
797c478bd9Sstevel@tonic-gate     return 0;
807c478bd9Sstevel@tonic-gate   }
817c478bd9Sstevel@tonic-gate   pNew->op = TK_FUNCTION;
827c478bd9Sstevel@tonic-gate   pNew->pList = pList;
837c478bd9Sstevel@tonic-gate   if( pToken ){
847c478bd9Sstevel@tonic-gate     assert( pToken->dyn==0 );
857c478bd9Sstevel@tonic-gate     pNew->token = *pToken;
867c478bd9Sstevel@tonic-gate   }else{
877c478bd9Sstevel@tonic-gate     pNew->token.z = 0;
887c478bd9Sstevel@tonic-gate   }
897c478bd9Sstevel@tonic-gate   pNew->span = pNew->token;
907c478bd9Sstevel@tonic-gate   return pNew;
917c478bd9Sstevel@tonic-gate }
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate /*
947c478bd9Sstevel@tonic-gate ** Recursively delete an expression tree.
957c478bd9Sstevel@tonic-gate */
sqliteExprDelete(Expr * p)967c478bd9Sstevel@tonic-gate void sqliteExprDelete(Expr *p){
977c478bd9Sstevel@tonic-gate   if( p==0 ) return;
987c478bd9Sstevel@tonic-gate   if( p->span.dyn ) sqliteFree((char*)p->span.z);
997c478bd9Sstevel@tonic-gate   if( p->token.dyn ) sqliteFree((char*)p->token.z);
1007c478bd9Sstevel@tonic-gate   sqliteExprDelete(p->pLeft);
1017c478bd9Sstevel@tonic-gate   sqliteExprDelete(p->pRight);
1027c478bd9Sstevel@tonic-gate   sqliteExprListDelete(p->pList);
1037c478bd9Sstevel@tonic-gate   sqliteSelectDelete(p->pSelect);
1047c478bd9Sstevel@tonic-gate   sqliteFree(p);
1057c478bd9Sstevel@tonic-gate }
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate /*
1097c478bd9Sstevel@tonic-gate ** The following group of routines make deep copies of expressions,
1107c478bd9Sstevel@tonic-gate ** expression lists, ID lists, and select statements.  The copies can
1117c478bd9Sstevel@tonic-gate ** be deleted (by being passed to their respective ...Delete() routines)
1127c478bd9Sstevel@tonic-gate ** without effecting the originals.
1137c478bd9Sstevel@tonic-gate **
1147c478bd9Sstevel@tonic-gate ** The expression list, ID, and source lists return by sqliteExprListDup(),
115*55fea89dSDan Cross ** sqliteIdListDup(), and sqliteSrcListDup() can not be further expanded
1167c478bd9Sstevel@tonic-gate ** by subsequent calls to sqlite*ListAppend() routines.
1177c478bd9Sstevel@tonic-gate **
1187c478bd9Sstevel@tonic-gate ** Any tables that the SrcList might point to are not duplicated.
1197c478bd9Sstevel@tonic-gate */
sqliteExprDup(Expr * p)1207c478bd9Sstevel@tonic-gate Expr *sqliteExprDup(Expr *p){
1217c478bd9Sstevel@tonic-gate   Expr *pNew;
1227c478bd9Sstevel@tonic-gate   if( p==0 ) return 0;
1237c478bd9Sstevel@tonic-gate   pNew = sqliteMallocRaw( sizeof(*p) );
1247c478bd9Sstevel@tonic-gate   if( pNew==0 ) return 0;
1257c478bd9Sstevel@tonic-gate   memcpy(pNew, p, sizeof(*pNew));
1267c478bd9Sstevel@tonic-gate   if( p->token.z!=0 ){
1277c478bd9Sstevel@tonic-gate     pNew->token.z = sqliteStrDup(p->token.z);
1287c478bd9Sstevel@tonic-gate     pNew->token.dyn = 1;
1297c478bd9Sstevel@tonic-gate   }else{
1307c478bd9Sstevel@tonic-gate     assert( pNew->token.z==0 );
1317c478bd9Sstevel@tonic-gate   }
1327c478bd9Sstevel@tonic-gate   pNew->span.z = 0;
1337c478bd9Sstevel@tonic-gate   pNew->pLeft = sqliteExprDup(p->pLeft);
1347c478bd9Sstevel@tonic-gate   pNew->pRight = sqliteExprDup(p->pRight);
1357c478bd9Sstevel@tonic-gate   pNew->pList = sqliteExprListDup(p->pList);
1367c478bd9Sstevel@tonic-gate   pNew->pSelect = sqliteSelectDup(p->pSelect);
1377c478bd9Sstevel@tonic-gate   return pNew;
1387c478bd9Sstevel@tonic-gate }
sqliteTokenCopy(Token * pTo,Token * pFrom)1397c478bd9Sstevel@tonic-gate void sqliteTokenCopy(Token *pTo, Token *pFrom){
1407c478bd9Sstevel@tonic-gate   if( pTo->dyn ) sqliteFree((char*)pTo->z);
1417c478bd9Sstevel@tonic-gate   if( pFrom->z ){
1427c478bd9Sstevel@tonic-gate     pTo->n = pFrom->n;
1437c478bd9Sstevel@tonic-gate     pTo->z = sqliteStrNDup(pFrom->z, pFrom->n);
1447c478bd9Sstevel@tonic-gate     pTo->dyn = 1;
1457c478bd9Sstevel@tonic-gate   }else{
1467c478bd9Sstevel@tonic-gate     pTo->z = 0;
1477c478bd9Sstevel@tonic-gate   }
1487c478bd9Sstevel@tonic-gate }
sqliteExprListDup(ExprList * p)1497c478bd9Sstevel@tonic-gate ExprList *sqliteExprListDup(ExprList *p){
1507c478bd9Sstevel@tonic-gate   ExprList *pNew;
1517c478bd9Sstevel@tonic-gate   struct ExprList_item *pItem;
1527c478bd9Sstevel@tonic-gate   int i;
1537c478bd9Sstevel@tonic-gate   if( p==0 ) return 0;
1547c478bd9Sstevel@tonic-gate   pNew = sqliteMalloc( sizeof(*pNew) );
1557c478bd9Sstevel@tonic-gate   if( pNew==0 ) return 0;
1567c478bd9Sstevel@tonic-gate   pNew->nExpr = pNew->nAlloc = p->nExpr;
1577c478bd9Sstevel@tonic-gate   pNew->a = pItem = sqliteMalloc( p->nExpr*sizeof(p->a[0]) );
1587c478bd9Sstevel@tonic-gate   if( pItem==0 ){
1597c478bd9Sstevel@tonic-gate     sqliteFree(pNew);
1607c478bd9Sstevel@tonic-gate     return 0;
1617c478bd9Sstevel@tonic-gate   }
1627c478bd9Sstevel@tonic-gate   for(i=0; i<p->nExpr; i++, pItem++){
1637c478bd9Sstevel@tonic-gate     Expr *pNewExpr, *pOldExpr;
1647c478bd9Sstevel@tonic-gate     pItem->pExpr = pNewExpr = sqliteExprDup(pOldExpr = p->a[i].pExpr);
1657c478bd9Sstevel@tonic-gate     if( pOldExpr->span.z!=0 && pNewExpr ){
1667c478bd9Sstevel@tonic-gate       /* Always make a copy of the span for top-level expressions in the
1677c478bd9Sstevel@tonic-gate       ** expression list.  The logic in SELECT processing that determines
1687c478bd9Sstevel@tonic-gate       ** the names of columns in the result set needs this information */
1697c478bd9Sstevel@tonic-gate       sqliteTokenCopy(&pNewExpr->span, &pOldExpr->span);
1707c478bd9Sstevel@tonic-gate     }
171*55fea89dSDan Cross     assert( pNewExpr==0 || pNewExpr->span.z!=0
1727c478bd9Sstevel@tonic-gate             || pOldExpr->span.z==0 || sqlite_malloc_failed );
1737c478bd9Sstevel@tonic-gate     pItem->zName = sqliteStrDup(p->a[i].zName);
1747c478bd9Sstevel@tonic-gate     pItem->sortOrder = p->a[i].sortOrder;
1757c478bd9Sstevel@tonic-gate     pItem->isAgg = p->a[i].isAgg;
1767c478bd9Sstevel@tonic-gate     pItem->done = 0;
1777c478bd9Sstevel@tonic-gate   }
1787c478bd9Sstevel@tonic-gate   return pNew;
1797c478bd9Sstevel@tonic-gate }
sqliteSrcListDup(SrcList * p)1807c478bd9Sstevel@tonic-gate SrcList *sqliteSrcListDup(SrcList *p){
1817c478bd9Sstevel@tonic-gate   SrcList *pNew;
1827c478bd9Sstevel@tonic-gate   int i;
1837c478bd9Sstevel@tonic-gate   int nByte;
1847c478bd9Sstevel@tonic-gate   if( p==0 ) return 0;
1857c478bd9Sstevel@tonic-gate   nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
1867c478bd9Sstevel@tonic-gate   pNew = sqliteMallocRaw( nByte );
1877c478bd9Sstevel@tonic-gate   if( pNew==0 ) return 0;
1887c478bd9Sstevel@tonic-gate   pNew->nSrc = pNew->nAlloc = p->nSrc;
1897c478bd9Sstevel@tonic-gate   for(i=0; i<p->nSrc; i++){
1907c478bd9Sstevel@tonic-gate     struct SrcList_item *pNewItem = &pNew->a[i];
1917c478bd9Sstevel@tonic-gate     struct SrcList_item *pOldItem = &p->a[i];
1927c478bd9Sstevel@tonic-gate     pNewItem->zDatabase = sqliteStrDup(pOldItem->zDatabase);
1937c478bd9Sstevel@tonic-gate     pNewItem->zName = sqliteStrDup(pOldItem->zName);
1947c478bd9Sstevel@tonic-gate     pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
1957c478bd9Sstevel@tonic-gate     pNewItem->jointype = pOldItem->jointype;
1967c478bd9Sstevel@tonic-gate     pNewItem->iCursor = pOldItem->iCursor;
1977c478bd9Sstevel@tonic-gate     pNewItem->pTab = 0;
1987c478bd9Sstevel@tonic-gate     pNewItem->pSelect = sqliteSelectDup(pOldItem->pSelect);
1997c478bd9Sstevel@tonic-gate     pNewItem->pOn = sqliteExprDup(pOldItem->pOn);
2007c478bd9Sstevel@tonic-gate     pNewItem->pUsing = sqliteIdListDup(pOldItem->pUsing);
2017c478bd9Sstevel@tonic-gate   }
2027c478bd9Sstevel@tonic-gate   return pNew;
2037c478bd9Sstevel@tonic-gate }
sqliteIdListDup(IdList * p)2047c478bd9Sstevel@tonic-gate IdList *sqliteIdListDup(IdList *p){
2057c478bd9Sstevel@tonic-gate   IdList *pNew;
2067c478bd9Sstevel@tonic-gate   int i;
2077c478bd9Sstevel@tonic-gate   if( p==0 ) return 0;
2087c478bd9Sstevel@tonic-gate   pNew = sqliteMallocRaw( sizeof(*pNew) );
2097c478bd9Sstevel@tonic-gate   if( pNew==0 ) return 0;
2107c478bd9Sstevel@tonic-gate   pNew->nId = pNew->nAlloc = p->nId;
2117c478bd9Sstevel@tonic-gate   pNew->a = sqliteMallocRaw( p->nId*sizeof(p->a[0]) );
2127c478bd9Sstevel@tonic-gate   if( pNew->a==0 ) return 0;
2137c478bd9Sstevel@tonic-gate   for(i=0; i<p->nId; i++){
2147c478bd9Sstevel@tonic-gate     struct IdList_item *pNewItem = &pNew->a[i];
2157c478bd9Sstevel@tonic-gate     struct IdList_item *pOldItem = &p->a[i];
2167c478bd9Sstevel@tonic-gate     pNewItem->zName = sqliteStrDup(pOldItem->zName);
2177c478bd9Sstevel@tonic-gate     pNewItem->idx = pOldItem->idx;
2187c478bd9Sstevel@tonic-gate   }
2197c478bd9Sstevel@tonic-gate   return pNew;
2207c478bd9Sstevel@tonic-gate }
sqliteSelectDup(Select * p)2217c478bd9Sstevel@tonic-gate Select *sqliteSelectDup(Select *p){
2227c478bd9Sstevel@tonic-gate   Select *pNew;
2237c478bd9Sstevel@tonic-gate   if( p==0 ) return 0;
2247c478bd9Sstevel@tonic-gate   pNew = sqliteMallocRaw( sizeof(*p) );
2257c478bd9Sstevel@tonic-gate   if( pNew==0 ) return 0;
2267c478bd9Sstevel@tonic-gate   pNew->isDistinct = p->isDistinct;
2277c478bd9Sstevel@tonic-gate   pNew->pEList = sqliteExprListDup(p->pEList);
2287c478bd9Sstevel@tonic-gate   pNew->pSrc = sqliteSrcListDup(p->pSrc);
2297c478bd9Sstevel@tonic-gate   pNew->pWhere = sqliteExprDup(p->pWhere);
2307c478bd9Sstevel@tonic-gate   pNew->pGroupBy = sqliteExprListDup(p->pGroupBy);
2317c478bd9Sstevel@tonic-gate   pNew->pHaving = sqliteExprDup(p->pHaving);
2327c478bd9Sstevel@tonic-gate   pNew->pOrderBy = sqliteExprListDup(p->pOrderBy);
2337c478bd9Sstevel@tonic-gate   pNew->op = p->op;
2347c478bd9Sstevel@tonic-gate   pNew->pPrior = sqliteSelectDup(p->pPrior);
2357c478bd9Sstevel@tonic-gate   pNew->nLimit = p->nLimit;
2367c478bd9Sstevel@tonic-gate   pNew->nOffset = p->nOffset;
2377c478bd9Sstevel@tonic-gate   pNew->zSelect = 0;
2387c478bd9Sstevel@tonic-gate   pNew->iLimit = -1;
2397c478bd9Sstevel@tonic-gate   pNew->iOffset = -1;
2407c478bd9Sstevel@tonic-gate   return pNew;
2417c478bd9Sstevel@tonic-gate }
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate /*
2457c478bd9Sstevel@tonic-gate ** Add a new element to the end of an expression list.  If pList is
2467c478bd9Sstevel@tonic-gate ** initially NULL, then create a new expression list.
2477c478bd9Sstevel@tonic-gate */
sqliteExprListAppend(ExprList * pList,Expr * pExpr,Token * pName)2487c478bd9Sstevel@tonic-gate ExprList *sqliteExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){
2497c478bd9Sstevel@tonic-gate   if( pList==0 ){
2507c478bd9Sstevel@tonic-gate     pList = sqliteMalloc( sizeof(ExprList) );
2517c478bd9Sstevel@tonic-gate     if( pList==0 ){
2527c478bd9Sstevel@tonic-gate       /* sqliteExprDelete(pExpr); // Leak memory if malloc fails */
2537c478bd9Sstevel@tonic-gate       return 0;
2547c478bd9Sstevel@tonic-gate     }
2557c478bd9Sstevel@tonic-gate     assert( pList->nAlloc==0 );
2567c478bd9Sstevel@tonic-gate   }
2577c478bd9Sstevel@tonic-gate   if( pList->nAlloc<=pList->nExpr ){
2587c478bd9Sstevel@tonic-gate     pList->nAlloc = pList->nAlloc*2 + 4;
2597c478bd9Sstevel@tonic-gate     pList->a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]));
2607c478bd9Sstevel@tonic-gate     if( pList->a==0 ){
2617c478bd9Sstevel@tonic-gate       /* sqliteExprDelete(pExpr); // Leak memory if malloc fails */
2627c478bd9Sstevel@tonic-gate       pList->nExpr = pList->nAlloc = 0;
2637c478bd9Sstevel@tonic-gate       return pList;
2647c478bd9Sstevel@tonic-gate     }
2657c478bd9Sstevel@tonic-gate   }
2667c478bd9Sstevel@tonic-gate   assert( pList->a!=0 );
2677c478bd9Sstevel@tonic-gate   if( pExpr || pName ){
2687c478bd9Sstevel@tonic-gate     struct ExprList_item *pItem = &pList->a[pList->nExpr++];
2697c478bd9Sstevel@tonic-gate     memset(pItem, 0, sizeof(*pItem));
2707c478bd9Sstevel@tonic-gate     pItem->pExpr = pExpr;
2717c478bd9Sstevel@tonic-gate     if( pName ){
2727c478bd9Sstevel@tonic-gate       sqliteSetNString(&pItem->zName, pName->z, pName->n, 0);
2737c478bd9Sstevel@tonic-gate       sqliteDequote(pItem->zName);
2747c478bd9Sstevel@tonic-gate     }
2757c478bd9Sstevel@tonic-gate   }
2767c478bd9Sstevel@tonic-gate   return pList;
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate /*
2807c478bd9Sstevel@tonic-gate ** Delete an entire expression list.
2817c478bd9Sstevel@tonic-gate */
sqliteExprListDelete(ExprList * pList)2827c478bd9Sstevel@tonic-gate void sqliteExprListDelete(ExprList *pList){
2837c478bd9Sstevel@tonic-gate   int i;
2847c478bd9Sstevel@tonic-gate   if( pList==0 ) return;
2857c478bd9Sstevel@tonic-gate   assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) );
2867c478bd9Sstevel@tonic-gate   assert( pList->nExpr<=pList->nAlloc );
2877c478bd9Sstevel@tonic-gate   for(i=0; i<pList->nExpr; i++){
2887c478bd9Sstevel@tonic-gate     sqliteExprDelete(pList->a[i].pExpr);
2897c478bd9Sstevel@tonic-gate     sqliteFree(pList->a[i].zName);
2907c478bd9Sstevel@tonic-gate   }
2917c478bd9Sstevel@tonic-gate   sqliteFree(pList->a);
2927c478bd9Sstevel@tonic-gate   sqliteFree(pList);
2937c478bd9Sstevel@tonic-gate }
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate /*
2967c478bd9Sstevel@tonic-gate ** Walk an expression tree.  Return 1 if the expression is constant
2977c478bd9Sstevel@tonic-gate ** and 0 if it involves variables.
2987c478bd9Sstevel@tonic-gate **
2997c478bd9Sstevel@tonic-gate ** For the purposes of this function, a double-quoted string (ex: "abc")
3007c478bd9Sstevel@tonic-gate ** is considered a variable but a single-quoted string (ex: 'abc') is
3017c478bd9Sstevel@tonic-gate ** a constant.
3027c478bd9Sstevel@tonic-gate */
sqliteExprIsConstant(Expr * p)3037c478bd9Sstevel@tonic-gate int sqliteExprIsConstant(Expr *p){
3047c478bd9Sstevel@tonic-gate   switch( p->op ){
3057c478bd9Sstevel@tonic-gate     case TK_ID:
3067c478bd9Sstevel@tonic-gate     case TK_COLUMN:
3077c478bd9Sstevel@tonic-gate     case TK_DOT:
3087c478bd9Sstevel@tonic-gate     case TK_FUNCTION:
3097c478bd9Sstevel@tonic-gate       return 0;
3107c478bd9Sstevel@tonic-gate     case TK_NULL:
3117c478bd9Sstevel@tonic-gate     case TK_STRING:
3127c478bd9Sstevel@tonic-gate     case TK_INTEGER:
3137c478bd9Sstevel@tonic-gate     case TK_FLOAT:
3147c478bd9Sstevel@tonic-gate     case TK_VARIABLE:
3157c478bd9Sstevel@tonic-gate       return 1;
3167c478bd9Sstevel@tonic-gate     default: {
3177c478bd9Sstevel@tonic-gate       if( p->pLeft && !sqliteExprIsConstant(p->pLeft) ) return 0;
3187c478bd9Sstevel@tonic-gate       if( p->pRight && !sqliteExprIsConstant(p->pRight) ) return 0;
3197c478bd9Sstevel@tonic-gate       if( p->pList ){
3207c478bd9Sstevel@tonic-gate         int i;
3217c478bd9Sstevel@tonic-gate         for(i=0; i<p->pList->nExpr; i++){
3227c478bd9Sstevel@tonic-gate           if( !sqliteExprIsConstant(p->pList->a[i].pExpr) ) return 0;
3237c478bd9Sstevel@tonic-gate         }
3247c478bd9Sstevel@tonic-gate       }
3257c478bd9Sstevel@tonic-gate       return p->pLeft!=0 || p->pRight!=0 || (p->pList && p->pList->nExpr>0);
3267c478bd9Sstevel@tonic-gate     }
3277c478bd9Sstevel@tonic-gate   }
3287c478bd9Sstevel@tonic-gate   return 0;
3297c478bd9Sstevel@tonic-gate }
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate /*
3327c478bd9Sstevel@tonic-gate ** If the given expression codes a constant integer that is small enough
3337c478bd9Sstevel@tonic-gate ** to fit in a 32-bit integer, return 1 and put the value of the integer
3347c478bd9Sstevel@tonic-gate ** in *pValue.  If the expression is not an integer or if it is too big
3357c478bd9Sstevel@tonic-gate ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
3367c478bd9Sstevel@tonic-gate */
sqliteExprIsInteger(Expr * p,int * pValue)3377c478bd9Sstevel@tonic-gate int sqliteExprIsInteger(Expr *p, int *pValue){
3387c478bd9Sstevel@tonic-gate   switch( p->op ){
3397c478bd9Sstevel@tonic-gate     case TK_INTEGER: {
3407c478bd9Sstevel@tonic-gate       if( sqliteFitsIn32Bits(p->token.z) ){
3417c478bd9Sstevel@tonic-gate         *pValue = atoi(p->token.z);
3427c478bd9Sstevel@tonic-gate         return 1;
3437c478bd9Sstevel@tonic-gate       }
3447c478bd9Sstevel@tonic-gate       break;
3457c478bd9Sstevel@tonic-gate     }
3467c478bd9Sstevel@tonic-gate     case TK_STRING: {
3477c478bd9Sstevel@tonic-gate       const char *z = p->token.z;
3487c478bd9Sstevel@tonic-gate       int n = p->token.n;
3497c478bd9Sstevel@tonic-gate       if( n>0 && z[0]=='-' ){ z++; n--; }
3507c478bd9Sstevel@tonic-gate       while( n>0 && *z && isdigit(*z) ){ z++; n--; }
3517c478bd9Sstevel@tonic-gate       if( n==0 && sqliteFitsIn32Bits(p->token.z) ){
3527c478bd9Sstevel@tonic-gate         *pValue = atoi(p->token.z);
3537c478bd9Sstevel@tonic-gate         return 1;
3547c478bd9Sstevel@tonic-gate       }
3557c478bd9Sstevel@tonic-gate       break;
3567c478bd9Sstevel@tonic-gate     }
3577c478bd9Sstevel@tonic-gate     case TK_UPLUS: {
3587c478bd9Sstevel@tonic-gate       return sqliteExprIsInteger(p->pLeft, pValue);
3597c478bd9Sstevel@tonic-gate     }
3607c478bd9Sstevel@tonic-gate     case TK_UMINUS: {
3617c478bd9Sstevel@tonic-gate       int v;
3627c478bd9Sstevel@tonic-gate       if( sqliteExprIsInteger(p->pLeft, &v) ){
3637c478bd9Sstevel@tonic-gate         *pValue = -v;
3647c478bd9Sstevel@tonic-gate         return 1;
3657c478bd9Sstevel@tonic-gate       }
3667c478bd9Sstevel@tonic-gate       break;
3677c478bd9Sstevel@tonic-gate     }
3687c478bd9Sstevel@tonic-gate     default: break;
3697c478bd9Sstevel@tonic-gate   }
3707c478bd9Sstevel@tonic-gate   return 0;
3717c478bd9Sstevel@tonic-gate }
3727c478bd9Sstevel@tonic-gate 
3737c478bd9Sstevel@tonic-gate /*
3747c478bd9Sstevel@tonic-gate ** Return TRUE if the given string is a row-id column name.
3757c478bd9Sstevel@tonic-gate */
sqliteIsRowid(const char * z)3767c478bd9Sstevel@tonic-gate int sqliteIsRowid(const char *z){
3777c478bd9Sstevel@tonic-gate   if( sqliteStrICmp(z, "_ROWID_")==0 ) return 1;
3787c478bd9Sstevel@tonic-gate   if( sqliteStrICmp(z, "ROWID")==0 ) return 1;
3797c478bd9Sstevel@tonic-gate   if( sqliteStrICmp(z, "OID")==0 ) return 1;
3807c478bd9Sstevel@tonic-gate   return 0;
3817c478bd9Sstevel@tonic-gate }
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate /*
3847c478bd9Sstevel@tonic-gate ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
385*55fea89dSDan Cross ** that name in the set of source tables in pSrcList and make the pExpr
3867c478bd9Sstevel@tonic-gate ** expression node refer back to that source column.  The following changes
3877c478bd9Sstevel@tonic-gate ** are made to pExpr:
3887c478bd9Sstevel@tonic-gate **
3897c478bd9Sstevel@tonic-gate **    pExpr->iDb           Set the index in db->aDb[] of the database holding
3907c478bd9Sstevel@tonic-gate **                         the table.
3917c478bd9Sstevel@tonic-gate **    pExpr->iTable        Set to the cursor number for the table obtained
3927c478bd9Sstevel@tonic-gate **                         from pSrcList.
3937c478bd9Sstevel@tonic-gate **    pExpr->iColumn       Set to the column number within the table.
3947c478bd9Sstevel@tonic-gate **    pExpr->dataType      Set to the appropriate data type for the column.
3957c478bd9Sstevel@tonic-gate **    pExpr->op            Set to TK_COLUMN.
3967c478bd9Sstevel@tonic-gate **    pExpr->pLeft         Any expression this points to is deleted
3977c478bd9Sstevel@tonic-gate **    pExpr->pRight        Any expression this points to is deleted.
3987c478bd9Sstevel@tonic-gate **
3997c478bd9Sstevel@tonic-gate ** The pDbToken is the name of the database (the "X").  This value may be
4007c478bd9Sstevel@tonic-gate ** NULL meaning that name is of the form Y.Z or Z.  Any available database
4017c478bd9Sstevel@tonic-gate ** can be used.  The pTableToken is the name of the table (the "Y").  This
4027c478bd9Sstevel@tonic-gate ** value can be NULL if pDbToken is also NULL.  If pTableToken is NULL it
4037c478bd9Sstevel@tonic-gate ** means that the form of the name is Z and that columns from any table
4047c478bd9Sstevel@tonic-gate ** can be used.
4057c478bd9Sstevel@tonic-gate **
4067c478bd9Sstevel@tonic-gate ** If the name cannot be resolved unambiguously, leave an error message
4077c478bd9Sstevel@tonic-gate ** in pParse and return non-zero.  Return zero on success.
4087c478bd9Sstevel@tonic-gate */
lookupName(Parse * pParse,Token * pDbToken,Token * pTableToken,Token * pColumnToken,SrcList * pSrcList,ExprList * pEList,Expr * pExpr)4097c478bd9Sstevel@tonic-gate static int lookupName(
4107c478bd9Sstevel@tonic-gate   Parse *pParse,      /* The parsing context */
4117c478bd9Sstevel@tonic-gate   Token *pDbToken,     /* Name of the database containing table, or NULL */
4127c478bd9Sstevel@tonic-gate   Token *pTableToken,  /* Name of table containing column, or NULL */
4137c478bd9Sstevel@tonic-gate   Token *pColumnToken, /* Name of the column. */
4147c478bd9Sstevel@tonic-gate   SrcList *pSrcList,   /* List of tables used to resolve column names */
4157c478bd9Sstevel@tonic-gate   ExprList *pEList,    /* List of expressions used to resolve "AS" */
4167c478bd9Sstevel@tonic-gate   Expr *pExpr          /* Make this EXPR node point to the selected column */
4177c478bd9Sstevel@tonic-gate ){
4187c478bd9Sstevel@tonic-gate   char *zDb = 0;       /* Name of the database.  The "X" in X.Y.Z */
4197c478bd9Sstevel@tonic-gate   char *zTab = 0;      /* Name of the table.  The "Y" in X.Y.Z or Y.Z */
4207c478bd9Sstevel@tonic-gate   char *zCol = 0;      /* Name of the column.  The "Z" */
4217c478bd9Sstevel@tonic-gate   int i, j;            /* Loop counters */
4227c478bd9Sstevel@tonic-gate   int cnt = 0;         /* Number of matching column names */
4237c478bd9Sstevel@tonic-gate   int cntTab = 0;      /* Number of matching table names */
4247c478bd9Sstevel@tonic-gate   sqlite *db = pParse->db;  /* The database */
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate   assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */
4277c478bd9Sstevel@tonic-gate   if( pDbToken && pDbToken->z ){
4287c478bd9Sstevel@tonic-gate     zDb = sqliteStrNDup(pDbToken->z, pDbToken->n);
4297c478bd9Sstevel@tonic-gate     sqliteDequote(zDb);
4307c478bd9Sstevel@tonic-gate   }else{
4317c478bd9Sstevel@tonic-gate     zDb = 0;
4327c478bd9Sstevel@tonic-gate   }
4337c478bd9Sstevel@tonic-gate   if( pTableToken && pTableToken->z ){
4347c478bd9Sstevel@tonic-gate     zTab = sqliteStrNDup(pTableToken->z, pTableToken->n);
4357c478bd9Sstevel@tonic-gate     sqliteDequote(zTab);
4367c478bd9Sstevel@tonic-gate   }else{
4377c478bd9Sstevel@tonic-gate     assert( zDb==0 );
4387c478bd9Sstevel@tonic-gate     zTab = 0;
4397c478bd9Sstevel@tonic-gate   }
4407c478bd9Sstevel@tonic-gate   zCol = sqliteStrNDup(pColumnToken->z, pColumnToken->n);
4417c478bd9Sstevel@tonic-gate   sqliteDequote(zCol);
4427c478bd9Sstevel@tonic-gate   if( sqlite_malloc_failed ){
4437c478bd9Sstevel@tonic-gate     return 1;  /* Leak memory (zDb and zTab) if malloc fails */
4447c478bd9Sstevel@tonic-gate   }
4457c478bd9Sstevel@tonic-gate   assert( zTab==0 || pEList==0 );
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate   pExpr->iTable = -1;
4487c478bd9Sstevel@tonic-gate   for(i=0; i<pSrcList->nSrc; i++){
4497c478bd9Sstevel@tonic-gate     struct SrcList_item *pItem = &pSrcList->a[i];
4507c478bd9Sstevel@tonic-gate     Table *pTab = pItem->pTab;
4517c478bd9Sstevel@tonic-gate     Column *pCol;
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate     if( pTab==0 ) continue;
4547c478bd9Sstevel@tonic-gate     assert( pTab->nCol>0 );
4557c478bd9Sstevel@tonic-gate     if( zTab ){
4567c478bd9Sstevel@tonic-gate       if( pItem->zAlias ){
4577c478bd9Sstevel@tonic-gate         char *zTabName = pItem->zAlias;
4587c478bd9Sstevel@tonic-gate         if( sqliteStrICmp(zTabName, zTab)!=0 ) continue;
4597c478bd9Sstevel@tonic-gate       }else{
4607c478bd9Sstevel@tonic-gate         char *zTabName = pTab->zName;
4617c478bd9Sstevel@tonic-gate         if( zTabName==0 || sqliteStrICmp(zTabName, zTab)!=0 ) continue;
4627c478bd9Sstevel@tonic-gate         if( zDb!=0 && sqliteStrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){
4637c478bd9Sstevel@tonic-gate           continue;
4647c478bd9Sstevel@tonic-gate         }
4657c478bd9Sstevel@tonic-gate       }
4667c478bd9Sstevel@tonic-gate     }
4677c478bd9Sstevel@tonic-gate     if( 0==(cntTab++) ){
4687c478bd9Sstevel@tonic-gate       pExpr->iTable = pItem->iCursor;
4697c478bd9Sstevel@tonic-gate       pExpr->iDb = pTab->iDb;
4707c478bd9Sstevel@tonic-gate     }
4717c478bd9Sstevel@tonic-gate     for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
4727c478bd9Sstevel@tonic-gate       if( sqliteStrICmp(pCol->zName, zCol)==0 ){
4737c478bd9Sstevel@tonic-gate         cnt++;
4747c478bd9Sstevel@tonic-gate         pExpr->iTable = pItem->iCursor;
4757c478bd9Sstevel@tonic-gate         pExpr->iDb = pTab->iDb;
4767c478bd9Sstevel@tonic-gate         /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
4777c478bd9Sstevel@tonic-gate         pExpr->iColumn = j==pTab->iPKey ? -1 : j;
4787c478bd9Sstevel@tonic-gate         pExpr->dataType = pCol->sortOrder & SQLITE_SO_TYPEMASK;
4797c478bd9Sstevel@tonic-gate         break;
4807c478bd9Sstevel@tonic-gate       }
4817c478bd9Sstevel@tonic-gate     }
4827c478bd9Sstevel@tonic-gate   }
4837c478bd9Sstevel@tonic-gate 
484*55fea89dSDan Cross   /* If we have not already resolved the name, then maybe
4857c478bd9Sstevel@tonic-gate   ** it is a new.* or old.* trigger argument reference
4867c478bd9Sstevel@tonic-gate   */
4877c478bd9Sstevel@tonic-gate   if( zDb==0 && zTab!=0 && cnt==0 && pParse->trigStack!=0 ){
4887c478bd9Sstevel@tonic-gate     TriggerStack *pTriggerStack = pParse->trigStack;
4897c478bd9Sstevel@tonic-gate     Table *pTab = 0;
4907c478bd9Sstevel@tonic-gate     if( pTriggerStack->newIdx != -1 && sqliteStrICmp("new", zTab) == 0 ){
4917c478bd9Sstevel@tonic-gate       pExpr->iTable = pTriggerStack->newIdx;
4927c478bd9Sstevel@tonic-gate       assert( pTriggerStack->pTab );
4937c478bd9Sstevel@tonic-gate       pTab = pTriggerStack->pTab;
4947c478bd9Sstevel@tonic-gate     }else if( pTriggerStack->oldIdx != -1 && sqliteStrICmp("old", zTab) == 0 ){
4957c478bd9Sstevel@tonic-gate       pExpr->iTable = pTriggerStack->oldIdx;
4967c478bd9Sstevel@tonic-gate       assert( pTriggerStack->pTab );
4977c478bd9Sstevel@tonic-gate       pTab = pTriggerStack->pTab;
4987c478bd9Sstevel@tonic-gate     }
4997c478bd9Sstevel@tonic-gate 
500*55fea89dSDan Cross     if( pTab ){
5017c478bd9Sstevel@tonic-gate       int j;
5027c478bd9Sstevel@tonic-gate       Column *pCol = pTab->aCol;
503*55fea89dSDan Cross 
5047c478bd9Sstevel@tonic-gate       pExpr->iDb = pTab->iDb;
5057c478bd9Sstevel@tonic-gate       cntTab++;
5067c478bd9Sstevel@tonic-gate       for(j=0; j < pTab->nCol; j++, pCol++) {
5077c478bd9Sstevel@tonic-gate         if( sqliteStrICmp(pCol->zName, zCol)==0 ){
5087c478bd9Sstevel@tonic-gate           cnt++;
5097c478bd9Sstevel@tonic-gate           pExpr->iColumn = j==pTab->iPKey ? -1 : j;
5107c478bd9Sstevel@tonic-gate           pExpr->dataType = pCol->sortOrder & SQLITE_SO_TYPEMASK;
5117c478bd9Sstevel@tonic-gate           break;
5127c478bd9Sstevel@tonic-gate         }
5137c478bd9Sstevel@tonic-gate       }
5147c478bd9Sstevel@tonic-gate     }
5157c478bd9Sstevel@tonic-gate   }
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate   /*
5187c478bd9Sstevel@tonic-gate   ** Perhaps the name is a reference to the ROWID
5197c478bd9Sstevel@tonic-gate   */
5207c478bd9Sstevel@tonic-gate   if( cnt==0 && cntTab==1 && sqliteIsRowid(zCol) ){
5217c478bd9Sstevel@tonic-gate     cnt = 1;
5227c478bd9Sstevel@tonic-gate     pExpr->iColumn = -1;
5237c478bd9Sstevel@tonic-gate     pExpr->dataType = SQLITE_SO_NUM;
5247c478bd9Sstevel@tonic-gate   }
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate   /*
5277c478bd9Sstevel@tonic-gate   ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z
5287c478bd9Sstevel@tonic-gate   ** might refer to an result-set alias.  This happens, for example, when
5297c478bd9Sstevel@tonic-gate   ** we are resolving names in the WHERE clause of the following command:
5307c478bd9Sstevel@tonic-gate   **
5317c478bd9Sstevel@tonic-gate   **     SELECT a+b AS x FROM table WHERE x<10;
5327c478bd9Sstevel@tonic-gate   **
5337c478bd9Sstevel@tonic-gate   ** In cases like this, replace pExpr with a copy of the expression that
5347c478bd9Sstevel@tonic-gate   ** forms the result set entry ("a+b" in the example) and return immediately.
5357c478bd9Sstevel@tonic-gate   ** Note that the expression in the result set should have already been
5367c478bd9Sstevel@tonic-gate   ** resolved by the time the WHERE clause is resolved.
5377c478bd9Sstevel@tonic-gate   */
5387c478bd9Sstevel@tonic-gate   if( cnt==0 && pEList!=0 ){
5397c478bd9Sstevel@tonic-gate     for(j=0; j<pEList->nExpr; j++){
5407c478bd9Sstevel@tonic-gate       char *zAs = pEList->a[j].zName;
5417c478bd9Sstevel@tonic-gate       if( zAs!=0 && sqliteStrICmp(zAs, zCol)==0 ){
5427c478bd9Sstevel@tonic-gate         assert( pExpr->pLeft==0 && pExpr->pRight==0 );
5437c478bd9Sstevel@tonic-gate         pExpr->op = TK_AS;
5447c478bd9Sstevel@tonic-gate         pExpr->iColumn = j;
5457c478bd9Sstevel@tonic-gate         pExpr->pLeft = sqliteExprDup(pEList->a[j].pExpr);
5467c478bd9Sstevel@tonic-gate         sqliteFree(zCol);
5477c478bd9Sstevel@tonic-gate         assert( zTab==0 && zDb==0 );
5487c478bd9Sstevel@tonic-gate         return 0;
5497c478bd9Sstevel@tonic-gate       }
550*55fea89dSDan Cross     }
5517c478bd9Sstevel@tonic-gate   }
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate   /*
5547c478bd9Sstevel@tonic-gate   ** If X and Y are NULL (in other words if only the column name Z is
5557c478bd9Sstevel@tonic-gate   ** supplied) and the value of Z is enclosed in double-quotes, then
5567c478bd9Sstevel@tonic-gate   ** Z is a string literal if it doesn't match any column names.  In that
5577c478bd9Sstevel@tonic-gate   ** case, we need to return right away and not make any changes to
5587c478bd9Sstevel@tonic-gate   ** pExpr.
5597c478bd9Sstevel@tonic-gate   */
5607c478bd9Sstevel@tonic-gate   if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){
5617c478bd9Sstevel@tonic-gate     sqliteFree(zCol);
5627c478bd9Sstevel@tonic-gate     return 0;
5637c478bd9Sstevel@tonic-gate   }
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate   /*
5667c478bd9Sstevel@tonic-gate   ** cnt==0 means there was not match.  cnt>1 means there were two or
5677c478bd9Sstevel@tonic-gate   ** more matches.  Either way, we have an error.
5687c478bd9Sstevel@tonic-gate   */
5697c478bd9Sstevel@tonic-gate   if( cnt!=1 ){
5707c478bd9Sstevel@tonic-gate     char *z = 0;
5717c478bd9Sstevel@tonic-gate     char *zErr;
5727c478bd9Sstevel@tonic-gate     zErr = cnt==0 ? "no such column: %s" : "ambiguous column name: %s";
5737c478bd9Sstevel@tonic-gate     if( zDb ){
5747c478bd9Sstevel@tonic-gate       sqliteSetString(&z, zDb, ".", zTab, ".", zCol, 0);
5757c478bd9Sstevel@tonic-gate     }else if( zTab ){
5767c478bd9Sstevel@tonic-gate       sqliteSetString(&z, zTab, ".", zCol, 0);
5777c478bd9Sstevel@tonic-gate     }else{
5787c478bd9Sstevel@tonic-gate       z = sqliteStrDup(zCol);
5797c478bd9Sstevel@tonic-gate     }
5807c478bd9Sstevel@tonic-gate     sqliteErrorMsg(pParse, zErr, z);
5817c478bd9Sstevel@tonic-gate     sqliteFree(z);
5827c478bd9Sstevel@tonic-gate   }
5837c478bd9Sstevel@tonic-gate 
5847c478bd9Sstevel@tonic-gate   /* Clean up and return
5857c478bd9Sstevel@tonic-gate   */
5867c478bd9Sstevel@tonic-gate   sqliteFree(zDb);
5877c478bd9Sstevel@tonic-gate   sqliteFree(zTab);
5887c478bd9Sstevel@tonic-gate   sqliteFree(zCol);
5897c478bd9Sstevel@tonic-gate   sqliteExprDelete(pExpr->pLeft);
5907c478bd9Sstevel@tonic-gate   pExpr->pLeft = 0;
5917c478bd9Sstevel@tonic-gate   sqliteExprDelete(pExpr->pRight);
5927c478bd9Sstevel@tonic-gate   pExpr->pRight = 0;
5937c478bd9Sstevel@tonic-gate   pExpr->op = TK_COLUMN;
5947c478bd9Sstevel@tonic-gate   sqliteAuthRead(pParse, pExpr, pSrcList);
5957c478bd9Sstevel@tonic-gate   return cnt!=1;
5967c478bd9Sstevel@tonic-gate }
5977c478bd9Sstevel@tonic-gate 
5987c478bd9Sstevel@tonic-gate /*
5997c478bd9Sstevel@tonic-gate ** This routine walks an expression tree and resolves references to
6007c478bd9Sstevel@tonic-gate ** table columns.  Nodes of the form ID.ID or ID resolve into an
601*55fea89dSDan Cross ** index to the table in the table list and a column offset.  The
6027c478bd9Sstevel@tonic-gate ** Expr.opcode for such nodes is changed to TK_COLUMN.  The Expr.iTable
6037c478bd9Sstevel@tonic-gate ** value is changed to the index of the referenced table in pTabList
6047c478bd9Sstevel@tonic-gate ** plus the "base" value.  The base value will ultimately become the
6057c478bd9Sstevel@tonic-gate ** VDBE cursor number for a cursor that is pointing into the referenced
606*55fea89dSDan Cross ** table.  The Expr.iColumn value is changed to the index of the column
6077c478bd9Sstevel@tonic-gate ** of the referenced table.  The Expr.iColumn value for the special
6087c478bd9Sstevel@tonic-gate ** ROWID column is -1.  Any INTEGER PRIMARY KEY column is tried as an
6097c478bd9Sstevel@tonic-gate ** alias for ROWID.
6107c478bd9Sstevel@tonic-gate **
6117c478bd9Sstevel@tonic-gate ** We also check for instances of the IN operator.  IN comes in two
6127c478bd9Sstevel@tonic-gate ** forms:
6137c478bd9Sstevel@tonic-gate **
6147c478bd9Sstevel@tonic-gate **           expr IN (exprlist)
6157c478bd9Sstevel@tonic-gate ** and
6167c478bd9Sstevel@tonic-gate **           expr IN (SELECT ...)
6177c478bd9Sstevel@tonic-gate **
6187c478bd9Sstevel@tonic-gate ** The first form is handled by creating a set holding the list
619*55fea89dSDan Cross ** of allowed values.  The second form causes the SELECT to generate
6207c478bd9Sstevel@tonic-gate ** a temporary table.
6217c478bd9Sstevel@tonic-gate **
6227c478bd9Sstevel@tonic-gate ** This routine also looks for scalar SELECTs that are part of an expression.
6237c478bd9Sstevel@tonic-gate ** If it finds any, it generates code to write the value of that select
6247c478bd9Sstevel@tonic-gate ** into a memory cell.
6257c478bd9Sstevel@tonic-gate **
6267c478bd9Sstevel@tonic-gate ** Unknown columns or tables provoke an error.  The function returns
6277c478bd9Sstevel@tonic-gate ** the number of errors seen and leaves an error message on pParse->zErrMsg.
6287c478bd9Sstevel@tonic-gate */
sqliteExprResolveIds(Parse * pParse,SrcList * pSrcList,ExprList * pEList,Expr * pExpr)6297c478bd9Sstevel@tonic-gate int sqliteExprResolveIds(
6307c478bd9Sstevel@tonic-gate   Parse *pParse,     /* The parser context */
6317c478bd9Sstevel@tonic-gate   SrcList *pSrcList, /* List of tables used to resolve column names */
6327c478bd9Sstevel@tonic-gate   ExprList *pEList,  /* List of expressions used to resolve "AS" */
6337c478bd9Sstevel@tonic-gate   Expr *pExpr        /* The expression to be analyzed. */
6347c478bd9Sstevel@tonic-gate ){
6357c478bd9Sstevel@tonic-gate   int i;
6367c478bd9Sstevel@tonic-gate 
6377c478bd9Sstevel@tonic-gate   if( pExpr==0 || pSrcList==0 ) return 0;
6387c478bd9Sstevel@tonic-gate   for(i=0; i<pSrcList->nSrc; i++){
6397c478bd9Sstevel@tonic-gate     assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab );
6407c478bd9Sstevel@tonic-gate   }
6417c478bd9Sstevel@tonic-gate   switch( pExpr->op ){
6427c478bd9Sstevel@tonic-gate     /* Double-quoted strings (ex: "abc") are used as identifiers if
6437c478bd9Sstevel@tonic-gate     ** possible.  Otherwise they remain as strings.  Single-quoted
6447c478bd9Sstevel@tonic-gate     ** strings (ex: 'abc') are always string literals.
6457c478bd9Sstevel@tonic-gate     */
6467c478bd9Sstevel@tonic-gate     case TK_STRING: {
6477c478bd9Sstevel@tonic-gate       if( pExpr->token.z[0]=='\'' ) break;
6487c478bd9Sstevel@tonic-gate       /* Fall thru into the TK_ID case if this is a double-quoted string */
6497c478bd9Sstevel@tonic-gate     }
6507c478bd9Sstevel@tonic-gate     /* A lone identifier is the name of a columnd.
6517c478bd9Sstevel@tonic-gate     */
65288e1588bSToomas Soome     /* FALLTHROUGH */
6537c478bd9Sstevel@tonic-gate     case TK_ID: {
6547c478bd9Sstevel@tonic-gate       if( lookupName(pParse, 0, 0, &pExpr->token, pSrcList, pEList, pExpr) ){
6557c478bd9Sstevel@tonic-gate         return 1;
6567c478bd9Sstevel@tonic-gate       }
657*55fea89dSDan Cross       break;
6587c478bd9Sstevel@tonic-gate     }
659*55fea89dSDan Cross 
6607c478bd9Sstevel@tonic-gate     /* A table name and column name:     ID.ID
6617c478bd9Sstevel@tonic-gate     ** Or a database, table and column:  ID.ID.ID
6627c478bd9Sstevel@tonic-gate     */
6637c478bd9Sstevel@tonic-gate     case TK_DOT: {
6647c478bd9Sstevel@tonic-gate       Token *pColumn;
6657c478bd9Sstevel@tonic-gate       Token *pTable;
6667c478bd9Sstevel@tonic-gate       Token *pDb;
6677c478bd9Sstevel@tonic-gate       Expr *pRight;
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate       pRight = pExpr->pRight;
6707c478bd9Sstevel@tonic-gate       if( pRight->op==TK_ID ){
6717c478bd9Sstevel@tonic-gate         pDb = 0;
6727c478bd9Sstevel@tonic-gate         pTable = &pExpr->pLeft->token;
6737c478bd9Sstevel@tonic-gate         pColumn = &pRight->token;
6747c478bd9Sstevel@tonic-gate       }else{
6757c478bd9Sstevel@tonic-gate         assert( pRight->op==TK_DOT );
6767c478bd9Sstevel@tonic-gate         pDb = &pExpr->pLeft->token;
6777c478bd9Sstevel@tonic-gate         pTable = &pRight->pLeft->token;
6787c478bd9Sstevel@tonic-gate         pColumn = &pRight->pRight->token;
6797c478bd9Sstevel@tonic-gate       }
6807c478bd9Sstevel@tonic-gate       if( lookupName(pParse, pDb, pTable, pColumn, pSrcList, 0, pExpr) ){
6817c478bd9Sstevel@tonic-gate         return 1;
6827c478bd9Sstevel@tonic-gate       }
6837c478bd9Sstevel@tonic-gate       break;
6847c478bd9Sstevel@tonic-gate     }
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate     case TK_IN: {
6877c478bd9Sstevel@tonic-gate       Vdbe *v = sqliteGetVdbe(pParse);
6887c478bd9Sstevel@tonic-gate       if( v==0 ) return 1;
6897c478bd9Sstevel@tonic-gate       if( sqliteExprResolveIds(pParse, pSrcList, pEList, pExpr->pLeft) ){
6907c478bd9Sstevel@tonic-gate         return 1;
6917c478bd9Sstevel@tonic-gate       }
6927c478bd9Sstevel@tonic-gate       if( pExpr->pSelect ){
6937c478bd9Sstevel@tonic-gate         /* Case 1:     expr IN (SELECT ...)
6947c478bd9Sstevel@tonic-gate         **
6957c478bd9Sstevel@tonic-gate         ** Generate code to write the results of the select into a temporary
6967c478bd9Sstevel@tonic-gate         ** table.  The cursor number of the temporary table has already
6977c478bd9Sstevel@tonic-gate         ** been put in iTable by sqliteExprResolveInSelect().
6987c478bd9Sstevel@tonic-gate         */
6997c478bd9Sstevel@tonic-gate         pExpr->iTable = pParse->nTab++;
7007c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_OpenTemp, pExpr->iTable, 1);
7017c478bd9Sstevel@tonic-gate         sqliteSelect(pParse, pExpr->pSelect, SRT_Set, pExpr->iTable, 0,0,0);
7027c478bd9Sstevel@tonic-gate       }else if( pExpr->pList ){
7037c478bd9Sstevel@tonic-gate         /* Case 2:     expr IN (exprlist)
7047c478bd9Sstevel@tonic-gate         **
7057c478bd9Sstevel@tonic-gate         ** Create a set to put the exprlist values in.  The Set id is stored
7067c478bd9Sstevel@tonic-gate         ** in iTable.
7077c478bd9Sstevel@tonic-gate         */
7087c478bd9Sstevel@tonic-gate         int i, iSet;
7097c478bd9Sstevel@tonic-gate         for(i=0; i<pExpr->pList->nExpr; i++){
7107c478bd9Sstevel@tonic-gate           Expr *pE2 = pExpr->pList->a[i].pExpr;
7117c478bd9Sstevel@tonic-gate           if( !sqliteExprIsConstant(pE2) ){
7127c478bd9Sstevel@tonic-gate             sqliteErrorMsg(pParse,
7137c478bd9Sstevel@tonic-gate               "right-hand side of IN operator must be constant");
7147c478bd9Sstevel@tonic-gate             return 1;
7157c478bd9Sstevel@tonic-gate           }
7167c478bd9Sstevel@tonic-gate           if( sqliteExprCheck(pParse, pE2, 0, 0) ){
7177c478bd9Sstevel@tonic-gate             return 1;
7187c478bd9Sstevel@tonic-gate           }
7197c478bd9Sstevel@tonic-gate         }
7207c478bd9Sstevel@tonic-gate         iSet = pExpr->iTable = pParse->nSet++;
7217c478bd9Sstevel@tonic-gate         for(i=0; i<pExpr->pList->nExpr; i++){
7227c478bd9Sstevel@tonic-gate           Expr *pE2 = pExpr->pList->a[i].pExpr;
7237c478bd9Sstevel@tonic-gate           switch( pE2->op ){
7247c478bd9Sstevel@tonic-gate             case TK_FLOAT:
7257c478bd9Sstevel@tonic-gate             case TK_INTEGER:
7267c478bd9Sstevel@tonic-gate             case TK_STRING: {
7277c478bd9Sstevel@tonic-gate               int addr;
7287c478bd9Sstevel@tonic-gate               assert( pE2->token.z );
7297c478bd9Sstevel@tonic-gate               addr = sqliteVdbeOp3(v, OP_SetInsert, iSet, 0,
7307c478bd9Sstevel@tonic-gate                                   pE2->token.z, pE2->token.n);
7317c478bd9Sstevel@tonic-gate               sqliteVdbeDequoteP3(v, addr);
7327c478bd9Sstevel@tonic-gate               break;
7337c478bd9Sstevel@tonic-gate             }
7347c478bd9Sstevel@tonic-gate             default: {
7357c478bd9Sstevel@tonic-gate               sqliteExprCode(pParse, pE2);
7367c478bd9Sstevel@tonic-gate               sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0);
7377c478bd9Sstevel@tonic-gate               break;
7387c478bd9Sstevel@tonic-gate             }
7397c478bd9Sstevel@tonic-gate           }
7407c478bd9Sstevel@tonic-gate         }
7417c478bd9Sstevel@tonic-gate       }
7427c478bd9Sstevel@tonic-gate       break;
7437c478bd9Sstevel@tonic-gate     }
7447c478bd9Sstevel@tonic-gate 
7457c478bd9Sstevel@tonic-gate     case TK_SELECT: {
7467c478bd9Sstevel@tonic-gate       /* This has to be a scalar SELECT.  Generate code to put the
7477c478bd9Sstevel@tonic-gate       ** value of this select in a memory cell and record the number
7487c478bd9Sstevel@tonic-gate       ** of the memory cell in iColumn.
7497c478bd9Sstevel@tonic-gate       */
7507c478bd9Sstevel@tonic-gate       pExpr->iColumn = pParse->nMem++;
7517c478bd9Sstevel@tonic-gate       if( sqliteSelect(pParse, pExpr->pSelect, SRT_Mem, pExpr->iColumn,0,0,0) ){
7527c478bd9Sstevel@tonic-gate         return 1;
7537c478bd9Sstevel@tonic-gate       }
7547c478bd9Sstevel@tonic-gate       break;
7557c478bd9Sstevel@tonic-gate     }
7567c478bd9Sstevel@tonic-gate 
7577c478bd9Sstevel@tonic-gate     /* For all else, just recursively walk the tree */
7587c478bd9Sstevel@tonic-gate     default: {
7597c478bd9Sstevel@tonic-gate       if( pExpr->pLeft
7607c478bd9Sstevel@tonic-gate       && sqliteExprResolveIds(pParse, pSrcList, pEList, pExpr->pLeft) ){
7617c478bd9Sstevel@tonic-gate         return 1;
7627c478bd9Sstevel@tonic-gate       }
763*55fea89dSDan Cross       if( pExpr->pRight
7647c478bd9Sstevel@tonic-gate       && sqliteExprResolveIds(pParse, pSrcList, pEList, pExpr->pRight) ){
7657c478bd9Sstevel@tonic-gate         return 1;
7667c478bd9Sstevel@tonic-gate       }
7677c478bd9Sstevel@tonic-gate       if( pExpr->pList ){
7687c478bd9Sstevel@tonic-gate         int i;
7697c478bd9Sstevel@tonic-gate         ExprList *pList = pExpr->pList;
7707c478bd9Sstevel@tonic-gate         for(i=0; i<pList->nExpr; i++){
7717c478bd9Sstevel@tonic-gate           Expr *pArg = pList->a[i].pExpr;
7727c478bd9Sstevel@tonic-gate           if( sqliteExprResolveIds(pParse, pSrcList, pEList, pArg) ){
7737c478bd9Sstevel@tonic-gate             return 1;
7747c478bd9Sstevel@tonic-gate           }
7757c478bd9Sstevel@tonic-gate         }
7767c478bd9Sstevel@tonic-gate       }
7777c478bd9Sstevel@tonic-gate     }
7787c478bd9Sstevel@tonic-gate   }
7797c478bd9Sstevel@tonic-gate   return 0;
7807c478bd9Sstevel@tonic-gate }
7817c478bd9Sstevel@tonic-gate 
7827c478bd9Sstevel@tonic-gate /*
7837c478bd9Sstevel@tonic-gate ** pExpr is a node that defines a function of some kind.  It might
7847c478bd9Sstevel@tonic-gate ** be a syntactic function like "count(x)" or it might be a function
785*55fea89dSDan Cross ** that implements an operator, like "a LIKE b".
7867c478bd9Sstevel@tonic-gate **
787*55fea89dSDan Cross ** This routine makes *pzName point to the name of the function and
7887c478bd9Sstevel@tonic-gate ** *pnName hold the number of characters in the function name.
7897c478bd9Sstevel@tonic-gate */
getFunctionName(Expr * pExpr,const char ** pzName,int * pnName)7907c478bd9Sstevel@tonic-gate static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){
7917c478bd9Sstevel@tonic-gate   switch( pExpr->op ){
7927c478bd9Sstevel@tonic-gate     case TK_FUNCTION: {
7937c478bd9Sstevel@tonic-gate       *pzName = pExpr->token.z;
7947c478bd9Sstevel@tonic-gate       *pnName = pExpr->token.n;
7957c478bd9Sstevel@tonic-gate       break;
7967c478bd9Sstevel@tonic-gate     }
7977c478bd9Sstevel@tonic-gate     case TK_LIKE: {
7987c478bd9Sstevel@tonic-gate       *pzName = "like";
7997c478bd9Sstevel@tonic-gate       *pnName = 4;
8007c478bd9Sstevel@tonic-gate       break;
8017c478bd9Sstevel@tonic-gate     }
8027c478bd9Sstevel@tonic-gate     case TK_GLOB: {
8037c478bd9Sstevel@tonic-gate       *pzName = "glob";
8047c478bd9Sstevel@tonic-gate       *pnName = 4;
8057c478bd9Sstevel@tonic-gate       break;
8067c478bd9Sstevel@tonic-gate     }
8077c478bd9Sstevel@tonic-gate     default: {
8087c478bd9Sstevel@tonic-gate       *pzName = "can't happen";
8097c478bd9Sstevel@tonic-gate       *pnName = 12;
8107c478bd9Sstevel@tonic-gate       break;
8117c478bd9Sstevel@tonic-gate     }
8127c478bd9Sstevel@tonic-gate   }
8137c478bd9Sstevel@tonic-gate }
8147c478bd9Sstevel@tonic-gate 
8157c478bd9Sstevel@tonic-gate /*
8167c478bd9Sstevel@tonic-gate ** Error check the functions in an expression.  Make sure all
8177c478bd9Sstevel@tonic-gate ** function names are recognized and all functions have the correct
8187c478bd9Sstevel@tonic-gate ** number of arguments.  Leave an error message in pParse->zErrMsg
8197c478bd9Sstevel@tonic-gate ** if anything is amiss.  Return the number of errors.
8207c478bd9Sstevel@tonic-gate **
8217c478bd9Sstevel@tonic-gate ** if pIsAgg is not null and this expression is an aggregate function
8227c478bd9Sstevel@tonic-gate ** (like count(*) or max(value)) then write a 1 into *pIsAgg.
8237c478bd9Sstevel@tonic-gate */
sqliteExprCheck(Parse * pParse,Expr * pExpr,int allowAgg,int * pIsAgg)8247c478bd9Sstevel@tonic-gate int sqliteExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){
8257c478bd9Sstevel@tonic-gate   int nErr = 0;
8267c478bd9Sstevel@tonic-gate   if( pExpr==0 ) return 0;
8277c478bd9Sstevel@tonic-gate   switch( pExpr->op ){
8287c478bd9Sstevel@tonic-gate     case TK_GLOB:
8297c478bd9Sstevel@tonic-gate     case TK_LIKE:
8307c478bd9Sstevel@tonic-gate     case TK_FUNCTION: {
8317c478bd9Sstevel@tonic-gate       int n = pExpr->pList ? pExpr->pList->nExpr : 0;  /* Number of arguments */
8327c478bd9Sstevel@tonic-gate       int no_such_func = 0;       /* True if no such function exists */
8337c478bd9Sstevel@tonic-gate       int wrong_num_args = 0;     /* True if wrong number of arguments */
8347c478bd9Sstevel@tonic-gate       int is_agg = 0;             /* True if is an aggregate function */
8357c478bd9Sstevel@tonic-gate       int i;
8367c478bd9Sstevel@tonic-gate       int nId;                    /* Number of characters in function name */
8377c478bd9Sstevel@tonic-gate       const char *zId;            /* The function name. */
8387c478bd9Sstevel@tonic-gate       FuncDef *pDef;
8397c478bd9Sstevel@tonic-gate 
8407c478bd9Sstevel@tonic-gate       getFunctionName(pExpr, &zId, &nId);
8417c478bd9Sstevel@tonic-gate       pDef = sqliteFindFunction(pParse->db, zId, nId, n, 0);
8427c478bd9Sstevel@tonic-gate       if( pDef==0 ){
8437c478bd9Sstevel@tonic-gate         pDef = sqliteFindFunction(pParse->db, zId, nId, -1, 0);
8447c478bd9Sstevel@tonic-gate         if( pDef==0 ){
8457c478bd9Sstevel@tonic-gate           no_such_func = 1;
8467c478bd9Sstevel@tonic-gate         }else{
8477c478bd9Sstevel@tonic-gate           wrong_num_args = 1;
8487c478bd9Sstevel@tonic-gate         }
8497c478bd9Sstevel@tonic-gate       }else{
8507c478bd9Sstevel@tonic-gate         is_agg = pDef->xFunc==0;
8517c478bd9Sstevel@tonic-gate       }
8527c478bd9Sstevel@tonic-gate       if( is_agg && !allowAgg ){
8537c478bd9Sstevel@tonic-gate         sqliteErrorMsg(pParse, "misuse of aggregate function %.*s()", nId, zId);
8547c478bd9Sstevel@tonic-gate         nErr++;
8557c478bd9Sstevel@tonic-gate         is_agg = 0;
8567c478bd9Sstevel@tonic-gate       }else if( no_such_func ){
8577c478bd9Sstevel@tonic-gate         sqliteErrorMsg(pParse, "no such function: %.*s", nId, zId);
8587c478bd9Sstevel@tonic-gate         nErr++;
8597c478bd9Sstevel@tonic-gate       }else if( wrong_num_args ){
8607c478bd9Sstevel@tonic-gate         sqliteErrorMsg(pParse,"wrong number of arguments to function %.*s()",
8617c478bd9Sstevel@tonic-gate              nId, zId);
8627c478bd9Sstevel@tonic-gate         nErr++;
8637c478bd9Sstevel@tonic-gate       }
8647c478bd9Sstevel@tonic-gate       if( is_agg ){
8657c478bd9Sstevel@tonic-gate         pExpr->op = TK_AGG_FUNCTION;
8667c478bd9Sstevel@tonic-gate         if( pIsAgg ) *pIsAgg = 1;
8677c478bd9Sstevel@tonic-gate       }
8687c478bd9Sstevel@tonic-gate       for(i=0; nErr==0 && i<n; i++){
8697c478bd9Sstevel@tonic-gate         nErr = sqliteExprCheck(pParse, pExpr->pList->a[i].pExpr,
8707c478bd9Sstevel@tonic-gate                                allowAgg && !is_agg, pIsAgg);
8717c478bd9Sstevel@tonic-gate       }
8727c478bd9Sstevel@tonic-gate       if( pDef==0 ){
8737c478bd9Sstevel@tonic-gate         /* Already reported an error */
8747c478bd9Sstevel@tonic-gate       }else if( pDef->dataType>=0 ){
8757c478bd9Sstevel@tonic-gate         if( pDef->dataType<n ){
876*55fea89dSDan Cross           pExpr->dataType =
8777c478bd9Sstevel@tonic-gate              sqliteExprType(pExpr->pList->a[pDef->dataType].pExpr);
8787c478bd9Sstevel@tonic-gate         }else{
8797c478bd9Sstevel@tonic-gate           pExpr->dataType = SQLITE_SO_NUM;
8807c478bd9Sstevel@tonic-gate         }
8817c478bd9Sstevel@tonic-gate       }else if( pDef->dataType==SQLITE_ARGS ){
8827c478bd9Sstevel@tonic-gate         pDef->dataType = SQLITE_SO_TEXT;
8837c478bd9Sstevel@tonic-gate         for(i=0; i<n; i++){
8847c478bd9Sstevel@tonic-gate           if( sqliteExprType(pExpr->pList->a[i].pExpr)==SQLITE_SO_NUM ){
8857c478bd9Sstevel@tonic-gate             pExpr->dataType = SQLITE_SO_NUM;
8867c478bd9Sstevel@tonic-gate             break;
8877c478bd9Sstevel@tonic-gate           }
8887c478bd9Sstevel@tonic-gate         }
8897c478bd9Sstevel@tonic-gate       }else if( pDef->dataType==SQLITE_NUMERIC ){
8907c478bd9Sstevel@tonic-gate         pExpr->dataType = SQLITE_SO_NUM;
8917c478bd9Sstevel@tonic-gate       }else{
8927c478bd9Sstevel@tonic-gate         pExpr->dataType = SQLITE_SO_TEXT;
8937c478bd9Sstevel@tonic-gate       }
8947c478bd9Sstevel@tonic-gate     }
89588e1588bSToomas Soome     /* FALLTHROUGH */
8967c478bd9Sstevel@tonic-gate     default: {
8977c478bd9Sstevel@tonic-gate       if( pExpr->pLeft ){
8987c478bd9Sstevel@tonic-gate         nErr = sqliteExprCheck(pParse, pExpr->pLeft, allowAgg, pIsAgg);
8997c478bd9Sstevel@tonic-gate       }
9007c478bd9Sstevel@tonic-gate       if( nErr==0 && pExpr->pRight ){
9017c478bd9Sstevel@tonic-gate         nErr = sqliteExprCheck(pParse, pExpr->pRight, allowAgg, pIsAgg);
9027c478bd9Sstevel@tonic-gate       }
9037c478bd9Sstevel@tonic-gate       if( nErr==0 && pExpr->pList ){
9047c478bd9Sstevel@tonic-gate         int n = pExpr->pList->nExpr;
9057c478bd9Sstevel@tonic-gate         int i;
9067c478bd9Sstevel@tonic-gate         for(i=0; nErr==0 && i<n; i++){
9077c478bd9Sstevel@tonic-gate           Expr *pE2 = pExpr->pList->a[i].pExpr;
9087c478bd9Sstevel@tonic-gate           nErr = sqliteExprCheck(pParse, pE2, allowAgg, pIsAgg);
9097c478bd9Sstevel@tonic-gate         }
9107c478bd9Sstevel@tonic-gate       }
9117c478bd9Sstevel@tonic-gate       break;
9127c478bd9Sstevel@tonic-gate     }
9137c478bd9Sstevel@tonic-gate   }
9147c478bd9Sstevel@tonic-gate   return nErr;
9157c478bd9Sstevel@tonic-gate }
9167c478bd9Sstevel@tonic-gate 
9177c478bd9Sstevel@tonic-gate /*
9187c478bd9Sstevel@tonic-gate ** Return either SQLITE_SO_NUM or SQLITE_SO_TEXT to indicate whether the
9197c478bd9Sstevel@tonic-gate ** given expression should sort as numeric values or as text.
9207c478bd9Sstevel@tonic-gate **
9217c478bd9Sstevel@tonic-gate ** The sqliteExprResolveIds() and sqliteExprCheck() routines must have
9227c478bd9Sstevel@tonic-gate ** both been called on the expression before it is passed to this routine.
9237c478bd9Sstevel@tonic-gate */
sqliteExprType(Expr * p)9247c478bd9Sstevel@tonic-gate int sqliteExprType(Expr *p){
9257c478bd9Sstevel@tonic-gate   if( p==0 ) return SQLITE_SO_NUM;
9267c478bd9Sstevel@tonic-gate   while( p ) switch( p->op ){
9277c478bd9Sstevel@tonic-gate     case TK_PLUS:
9287c478bd9Sstevel@tonic-gate     case TK_MINUS:
9297c478bd9Sstevel@tonic-gate     case TK_STAR:
9307c478bd9Sstevel@tonic-gate     case TK_SLASH:
9317c478bd9Sstevel@tonic-gate     case TK_AND:
9327c478bd9Sstevel@tonic-gate     case TK_OR:
9337c478bd9Sstevel@tonic-gate     case TK_ISNULL:
9347c478bd9Sstevel@tonic-gate     case TK_NOTNULL:
9357c478bd9Sstevel@tonic-gate     case TK_NOT:
9367c478bd9Sstevel@tonic-gate     case TK_UMINUS:
9377c478bd9Sstevel@tonic-gate     case TK_UPLUS:
9387c478bd9Sstevel@tonic-gate     case TK_BITAND:
9397c478bd9Sstevel@tonic-gate     case TK_BITOR:
9407c478bd9Sstevel@tonic-gate     case TK_BITNOT:
9417c478bd9Sstevel@tonic-gate     case TK_LSHIFT:
9427c478bd9Sstevel@tonic-gate     case TK_RSHIFT:
9437c478bd9Sstevel@tonic-gate     case TK_REM:
9447c478bd9Sstevel@tonic-gate     case TK_INTEGER:
9457c478bd9Sstevel@tonic-gate     case TK_FLOAT:
9467c478bd9Sstevel@tonic-gate     case TK_IN:
9477c478bd9Sstevel@tonic-gate     case TK_BETWEEN:
9487c478bd9Sstevel@tonic-gate     case TK_GLOB:
9497c478bd9Sstevel@tonic-gate     case TK_LIKE:
9507c478bd9Sstevel@tonic-gate       return SQLITE_SO_NUM;
9517c478bd9Sstevel@tonic-gate 
9527c478bd9Sstevel@tonic-gate     case TK_STRING:
9537c478bd9Sstevel@tonic-gate     case TK_NULL:
9547c478bd9Sstevel@tonic-gate     case TK_CONCAT:
9557c478bd9Sstevel@tonic-gate     case TK_VARIABLE:
9567c478bd9Sstevel@tonic-gate       return SQLITE_SO_TEXT;
9577c478bd9Sstevel@tonic-gate 
9587c478bd9Sstevel@tonic-gate     case TK_LT:
9597c478bd9Sstevel@tonic-gate     case TK_LE:
9607c478bd9Sstevel@tonic-gate     case TK_GT:
9617c478bd9Sstevel@tonic-gate     case TK_GE:
9627c478bd9Sstevel@tonic-gate     case TK_NE:
9637c478bd9Sstevel@tonic-gate     case TK_EQ:
9647c478bd9Sstevel@tonic-gate       if( sqliteExprType(p->pLeft)==SQLITE_SO_NUM ){
9657c478bd9Sstevel@tonic-gate         return SQLITE_SO_NUM;
9667c478bd9Sstevel@tonic-gate       }
9677c478bd9Sstevel@tonic-gate       p = p->pRight;
9687c478bd9Sstevel@tonic-gate       break;
9697c478bd9Sstevel@tonic-gate 
9707c478bd9Sstevel@tonic-gate     case TK_AS:
9717c478bd9Sstevel@tonic-gate       p = p->pLeft;
9727c478bd9Sstevel@tonic-gate       break;
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate     case TK_COLUMN:
9757c478bd9Sstevel@tonic-gate     case TK_FUNCTION:
9767c478bd9Sstevel@tonic-gate     case TK_AGG_FUNCTION:
9777c478bd9Sstevel@tonic-gate       return p->dataType;
9787c478bd9Sstevel@tonic-gate 
9797c478bd9Sstevel@tonic-gate     case TK_SELECT:
9807c478bd9Sstevel@tonic-gate       assert( p->pSelect );
9817c478bd9Sstevel@tonic-gate       assert( p->pSelect->pEList );
9827c478bd9Sstevel@tonic-gate       assert( p->pSelect->pEList->nExpr>0 );
9837c478bd9Sstevel@tonic-gate       p = p->pSelect->pEList->a[0].pExpr;
9847c478bd9Sstevel@tonic-gate       break;
9857c478bd9Sstevel@tonic-gate 
9867c478bd9Sstevel@tonic-gate     case TK_CASE: {
9877c478bd9Sstevel@tonic-gate       if( p->pRight && sqliteExprType(p->pRight)==SQLITE_SO_NUM ){
9887c478bd9Sstevel@tonic-gate         return SQLITE_SO_NUM;
9897c478bd9Sstevel@tonic-gate       }
9907c478bd9Sstevel@tonic-gate       if( p->pList ){
9917c478bd9Sstevel@tonic-gate         int i;
9927c478bd9Sstevel@tonic-gate         ExprList *pList = p->pList;
9937c478bd9Sstevel@tonic-gate         for(i=1; i<pList->nExpr; i+=2){
9947c478bd9Sstevel@tonic-gate           if( sqliteExprType(pList->a[i].pExpr)==SQLITE_SO_NUM ){
9957c478bd9Sstevel@tonic-gate             return SQLITE_SO_NUM;
9967c478bd9Sstevel@tonic-gate           }
9977c478bd9Sstevel@tonic-gate         }
9987c478bd9Sstevel@tonic-gate       }
9997c478bd9Sstevel@tonic-gate       return SQLITE_SO_TEXT;
10007c478bd9Sstevel@tonic-gate     }
10017c478bd9Sstevel@tonic-gate 
10027c478bd9Sstevel@tonic-gate     default:
10037c478bd9Sstevel@tonic-gate       assert( p->op==TK_ABORT );  /* Can't Happen */
10047c478bd9Sstevel@tonic-gate       break;
10057c478bd9Sstevel@tonic-gate   }
10067c478bd9Sstevel@tonic-gate   return SQLITE_SO_NUM;
10077c478bd9Sstevel@tonic-gate }
10087c478bd9Sstevel@tonic-gate 
10097c478bd9Sstevel@tonic-gate /*
10107c478bd9Sstevel@tonic-gate ** Generate code into the current Vdbe to evaluate the given
10117c478bd9Sstevel@tonic-gate ** expression and leave the result on the top of stack.
10127c478bd9Sstevel@tonic-gate */
sqliteExprCode(Parse * pParse,Expr * pExpr)10137c478bd9Sstevel@tonic-gate void sqliteExprCode(Parse *pParse, Expr *pExpr){
10147c478bd9Sstevel@tonic-gate   Vdbe *v = pParse->pVdbe;
10157c478bd9Sstevel@tonic-gate   int op;
10167c478bd9Sstevel@tonic-gate   if( v==0 || pExpr==0 ) return;
10177c478bd9Sstevel@tonic-gate   switch( pExpr->op ){
10187c478bd9Sstevel@tonic-gate     case TK_PLUS:     op = OP_Add;      break;
10197c478bd9Sstevel@tonic-gate     case TK_MINUS:    op = OP_Subtract; break;
10207c478bd9Sstevel@tonic-gate     case TK_STAR:     op = OP_Multiply; break;
10217c478bd9Sstevel@tonic-gate     case TK_SLASH:    op = OP_Divide;   break;
10227c478bd9Sstevel@tonic-gate     case TK_AND:      op = OP_And;      break;
10237c478bd9Sstevel@tonic-gate     case TK_OR:       op = OP_Or;       break;
10247c478bd9Sstevel@tonic-gate     case TK_LT:       op = OP_Lt;       break;
10257c478bd9Sstevel@tonic-gate     case TK_LE:       op = OP_Le;       break;
10267c478bd9Sstevel@tonic-gate     case TK_GT:       op = OP_Gt;       break;
10277c478bd9Sstevel@tonic-gate     case TK_GE:       op = OP_Ge;       break;
10287c478bd9Sstevel@tonic-gate     case TK_NE:       op = OP_Ne;       break;
10297c478bd9Sstevel@tonic-gate     case TK_EQ:       op = OP_Eq;       break;
10307c478bd9Sstevel@tonic-gate     case TK_ISNULL:   op = OP_IsNull;   break;
10317c478bd9Sstevel@tonic-gate     case TK_NOTNULL:  op = OP_NotNull;  break;
10327c478bd9Sstevel@tonic-gate     case TK_NOT:      op = OP_Not;      break;
10337c478bd9Sstevel@tonic-gate     case TK_UMINUS:   op = OP_Negative; break;
10347c478bd9Sstevel@tonic-gate     case TK_BITAND:   op = OP_BitAnd;   break;
10357c478bd9Sstevel@tonic-gate     case TK_BITOR:    op = OP_BitOr;    break;
10367c478bd9Sstevel@tonic-gate     case TK_BITNOT:   op = OP_BitNot;   break;
10377c478bd9Sstevel@tonic-gate     case TK_LSHIFT:   op = OP_ShiftLeft;  break;
10387c478bd9Sstevel@tonic-gate     case TK_RSHIFT:   op = OP_ShiftRight; break;
10397c478bd9Sstevel@tonic-gate     case TK_REM:      op = OP_Remainder;  break;
10407c478bd9Sstevel@tonic-gate     default: break;
10417c478bd9Sstevel@tonic-gate   }
10427c478bd9Sstevel@tonic-gate   switch( pExpr->op ){
10437c478bd9Sstevel@tonic-gate     case TK_COLUMN: {
10447c478bd9Sstevel@tonic-gate       if( pParse->useAgg ){
10457c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
10467c478bd9Sstevel@tonic-gate       }else if( pExpr->iColumn>=0 ){
10477c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
10487c478bd9Sstevel@tonic-gate       }else{
10497c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Recno, pExpr->iTable, 0);
10507c478bd9Sstevel@tonic-gate       }
10517c478bd9Sstevel@tonic-gate       break;
10527c478bd9Sstevel@tonic-gate     }
10537c478bd9Sstevel@tonic-gate     case TK_STRING:
10547c478bd9Sstevel@tonic-gate     case TK_FLOAT:
10557c478bd9Sstevel@tonic-gate     case TK_INTEGER: {
10567c478bd9Sstevel@tonic-gate       if( pExpr->op==TK_INTEGER && sqliteFitsIn32Bits(pExpr->token.z) ){
10577c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Integer, atoi(pExpr->token.z), 0);
10587c478bd9Sstevel@tonic-gate       }else{
10597c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_String, 0, 0);
10607c478bd9Sstevel@tonic-gate       }
10617c478bd9Sstevel@tonic-gate       assert( pExpr->token.z );
10627c478bd9Sstevel@tonic-gate       sqliteVdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n);
10637c478bd9Sstevel@tonic-gate       sqliteVdbeDequoteP3(v, -1);
10647c478bd9Sstevel@tonic-gate       break;
10657c478bd9Sstevel@tonic-gate     }
10667c478bd9Sstevel@tonic-gate     case TK_NULL: {
10677c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_String, 0, 0);
10687c478bd9Sstevel@tonic-gate       break;
10697c478bd9Sstevel@tonic-gate     }
10707c478bd9Sstevel@tonic-gate     case TK_VARIABLE: {
10717c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
10727c478bd9Sstevel@tonic-gate       break;
10737c478bd9Sstevel@tonic-gate     }
10747c478bd9Sstevel@tonic-gate     case TK_LT:
10757c478bd9Sstevel@tonic-gate     case TK_LE:
10767c478bd9Sstevel@tonic-gate     case TK_GT:
10777c478bd9Sstevel@tonic-gate     case TK_GE:
10787c478bd9Sstevel@tonic-gate     case TK_NE:
10797c478bd9Sstevel@tonic-gate     case TK_EQ: {
10807c478bd9Sstevel@tonic-gate       if( pParse->db->file_format>=4 && sqliteExprType(pExpr)==SQLITE_SO_TEXT ){
10817c478bd9Sstevel@tonic-gate         op += 6;  /* Convert numeric opcodes to text opcodes */
10827c478bd9Sstevel@tonic-gate       }
10837c478bd9Sstevel@tonic-gate     }
108488e1588bSToomas Soome     /* FALLTHROUGH */
10857c478bd9Sstevel@tonic-gate     case TK_AND:
10867c478bd9Sstevel@tonic-gate     case TK_OR:
10877c478bd9Sstevel@tonic-gate     case TK_PLUS:
10887c478bd9Sstevel@tonic-gate     case TK_STAR:
10897c478bd9Sstevel@tonic-gate     case TK_MINUS:
10907c478bd9Sstevel@tonic-gate     case TK_REM:
10917c478bd9Sstevel@tonic-gate     case TK_BITAND:
10927c478bd9Sstevel@tonic-gate     case TK_BITOR:
10937c478bd9Sstevel@tonic-gate     case TK_SLASH: {
10947c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
10957c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pRight);
10967c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, op, 0, 0);
10977c478bd9Sstevel@tonic-gate       break;
10987c478bd9Sstevel@tonic-gate     }
10997c478bd9Sstevel@tonic-gate     case TK_LSHIFT:
11007c478bd9Sstevel@tonic-gate     case TK_RSHIFT: {
11017c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pRight);
11027c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
11037c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, op, 0, 0);
11047c478bd9Sstevel@tonic-gate       break;
11057c478bd9Sstevel@tonic-gate     }
11067c478bd9Sstevel@tonic-gate     case TK_CONCAT: {
11077c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
11087c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pRight);
11097c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Concat, 2, 0);
11107c478bd9Sstevel@tonic-gate       break;
11117c478bd9Sstevel@tonic-gate     }
11127c478bd9Sstevel@tonic-gate     case TK_UMINUS: {
11137c478bd9Sstevel@tonic-gate       assert( pExpr->pLeft );
11147c478bd9Sstevel@tonic-gate       if( pExpr->pLeft->op==TK_FLOAT || pExpr->pLeft->op==TK_INTEGER ){
11157c478bd9Sstevel@tonic-gate         Token *p = &pExpr->pLeft->token;
11167c478bd9Sstevel@tonic-gate         char *z = sqliteMalloc( p->n + 2 );
11177c478bd9Sstevel@tonic-gate         sprintf(z, "-%.*s", p->n, p->z);
11187c478bd9Sstevel@tonic-gate         if( pExpr->pLeft->op==TK_INTEGER && sqliteFitsIn32Bits(z) ){
11197c478bd9Sstevel@tonic-gate           sqliteVdbeAddOp(v, OP_Integer, atoi(z), 0);
11207c478bd9Sstevel@tonic-gate         }else{
11217c478bd9Sstevel@tonic-gate           sqliteVdbeAddOp(v, OP_String, 0, 0);
11227c478bd9Sstevel@tonic-gate         }
11237c478bd9Sstevel@tonic-gate         sqliteVdbeChangeP3(v, -1, z, p->n+1);
11247c478bd9Sstevel@tonic-gate         sqliteFree(z);
11257c478bd9Sstevel@tonic-gate         break;
11267c478bd9Sstevel@tonic-gate       }
11277c478bd9Sstevel@tonic-gate       /* Fall through into TK_NOT */
11287c478bd9Sstevel@tonic-gate     }
112988e1588bSToomas Soome     /* FALLTHROUGH */
11307c478bd9Sstevel@tonic-gate     case TK_BITNOT:
11317c478bd9Sstevel@tonic-gate     case TK_NOT: {
11327c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
11337c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, op, 0, 0);
11347c478bd9Sstevel@tonic-gate       break;
11357c478bd9Sstevel@tonic-gate     }
11367c478bd9Sstevel@tonic-gate     case TK_ISNULL:
11377c478bd9Sstevel@tonic-gate     case TK_NOTNULL: {
11387c478bd9Sstevel@tonic-gate       int dest;
11397c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Integer, 1, 0);
11407c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
11417c478bd9Sstevel@tonic-gate       dest = sqliteVdbeCurrentAddr(v) + 2;
11427c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, op, 1, dest);
11437c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_AddImm, -1, 0);
11447c478bd9Sstevel@tonic-gate       break;
11457c478bd9Sstevel@tonic-gate     }
11467c478bd9Sstevel@tonic-gate     case TK_AGG_FUNCTION: {
11477c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
11487c478bd9Sstevel@tonic-gate       break;
11497c478bd9Sstevel@tonic-gate     }
11507c478bd9Sstevel@tonic-gate     case TK_GLOB:
11517c478bd9Sstevel@tonic-gate     case TK_LIKE:
11527c478bd9Sstevel@tonic-gate     case TK_FUNCTION: {
11537c478bd9Sstevel@tonic-gate       ExprList *pList = pExpr->pList;
11547c478bd9Sstevel@tonic-gate       int nExpr = pList ? pList->nExpr : 0;
11557c478bd9Sstevel@tonic-gate       FuncDef *pDef;
11567c478bd9Sstevel@tonic-gate       int nId;
11577c478bd9Sstevel@tonic-gate       const char *zId;
11587c478bd9Sstevel@tonic-gate       getFunctionName(pExpr, &zId, &nId);
11597c478bd9Sstevel@tonic-gate       pDef = sqliteFindFunction(pParse->db, zId, nId, nExpr, 0);
11607c478bd9Sstevel@tonic-gate       assert( pDef!=0 );
11617c478bd9Sstevel@tonic-gate       nExpr = sqliteExprCodeExprList(pParse, pList, pDef->includeTypes);
11627c478bd9Sstevel@tonic-gate       sqliteVdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_POINTER);
11637c478bd9Sstevel@tonic-gate       break;
11647c478bd9Sstevel@tonic-gate     }
11657c478bd9Sstevel@tonic-gate     case TK_SELECT: {
11667c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
11677c478bd9Sstevel@tonic-gate       break;
11687c478bd9Sstevel@tonic-gate     }
11697c478bd9Sstevel@tonic-gate     case TK_IN: {
11707c478bd9Sstevel@tonic-gate       int addr;
11717c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Integer, 1, 0);
11727c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
11737c478bd9Sstevel@tonic-gate       addr = sqliteVdbeCurrentAddr(v);
11747c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_NotNull, -1, addr+4);
11757c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Pop, 2, 0);
11767c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_String, 0, 0);
11777c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Goto, 0, addr+6);
11787c478bd9Sstevel@tonic-gate       if( pExpr->pSelect ){
11797c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, addr+6);
11807c478bd9Sstevel@tonic-gate       }else{
11817c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, addr+6);
11827c478bd9Sstevel@tonic-gate       }
11837c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_AddImm, -1, 0);
11847c478bd9Sstevel@tonic-gate       break;
11857c478bd9Sstevel@tonic-gate     }
11867c478bd9Sstevel@tonic-gate     case TK_BETWEEN: {
11877c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
11887c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Dup, 0, 0);
11897c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pList->a[0].pExpr);
11907c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Ge, 0, 0);
11917c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Pull, 1, 0);
11927c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
11937c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Le, 0, 0);
11947c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_And, 0, 0);
11957c478bd9Sstevel@tonic-gate       break;
11967c478bd9Sstevel@tonic-gate     }
11977c478bd9Sstevel@tonic-gate     case TK_UPLUS:
11987c478bd9Sstevel@tonic-gate     case TK_AS: {
11997c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
12007c478bd9Sstevel@tonic-gate       break;
12017c478bd9Sstevel@tonic-gate     }
12027c478bd9Sstevel@tonic-gate     case TK_CASE: {
12037c478bd9Sstevel@tonic-gate       int expr_end_label;
12047c478bd9Sstevel@tonic-gate       int jumpInst;
12057c478bd9Sstevel@tonic-gate       int addr;
12067c478bd9Sstevel@tonic-gate       int nExpr;
12077c478bd9Sstevel@tonic-gate       int i;
12087c478bd9Sstevel@tonic-gate 
12097c478bd9Sstevel@tonic-gate       assert(pExpr->pList);
12107c478bd9Sstevel@tonic-gate       assert((pExpr->pList->nExpr % 2) == 0);
12117c478bd9Sstevel@tonic-gate       assert(pExpr->pList->nExpr > 0);
12127c478bd9Sstevel@tonic-gate       nExpr = pExpr->pList->nExpr;
12137c478bd9Sstevel@tonic-gate       expr_end_label = sqliteVdbeMakeLabel(v);
12147c478bd9Sstevel@tonic-gate       if( pExpr->pLeft ){
12157c478bd9Sstevel@tonic-gate         sqliteExprCode(pParse, pExpr->pLeft);
12167c478bd9Sstevel@tonic-gate       }
12177c478bd9Sstevel@tonic-gate       for(i=0; i<nExpr; i=i+2){
12187c478bd9Sstevel@tonic-gate         sqliteExprCode(pParse, pExpr->pList->a[i].pExpr);
12197c478bd9Sstevel@tonic-gate         if( pExpr->pLeft ){
12207c478bd9Sstevel@tonic-gate           sqliteVdbeAddOp(v, OP_Dup, 1, 1);
12217c478bd9Sstevel@tonic-gate           jumpInst = sqliteVdbeAddOp(v, OP_Ne, 1, 0);
12227c478bd9Sstevel@tonic-gate           sqliteVdbeAddOp(v, OP_Pop, 1, 0);
12237c478bd9Sstevel@tonic-gate         }else{
12247c478bd9Sstevel@tonic-gate           jumpInst = sqliteVdbeAddOp(v, OP_IfNot, 1, 0);
12257c478bd9Sstevel@tonic-gate         }
12267c478bd9Sstevel@tonic-gate         sqliteExprCode(pParse, pExpr->pList->a[i+1].pExpr);
12277c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Goto, 0, expr_end_label);
12287c478bd9Sstevel@tonic-gate         addr = sqliteVdbeCurrentAddr(v);
12297c478bd9Sstevel@tonic-gate         sqliteVdbeChangeP2(v, jumpInst, addr);
12307c478bd9Sstevel@tonic-gate       }
12317c478bd9Sstevel@tonic-gate       if( pExpr->pLeft ){
12327c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Pop, 1, 0);
12337c478bd9Sstevel@tonic-gate       }
12347c478bd9Sstevel@tonic-gate       if( pExpr->pRight ){
12357c478bd9Sstevel@tonic-gate         sqliteExprCode(pParse, pExpr->pRight);
12367c478bd9Sstevel@tonic-gate       }else{
12377c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_String, 0, 0);
12387c478bd9Sstevel@tonic-gate       }
12397c478bd9Sstevel@tonic-gate       sqliteVdbeResolveLabel(v, expr_end_label);
12407c478bd9Sstevel@tonic-gate       break;
12417c478bd9Sstevel@tonic-gate     }
12427c478bd9Sstevel@tonic-gate     case TK_RAISE: {
12437c478bd9Sstevel@tonic-gate       if( !pParse->trigStack ){
12447c478bd9Sstevel@tonic-gate         sqliteErrorMsg(pParse,
12457c478bd9Sstevel@tonic-gate                        "RAISE() may only be used within a trigger-program");
12467c478bd9Sstevel@tonic-gate         pParse->nErr++;
12477c478bd9Sstevel@tonic-gate 	return;
12487c478bd9Sstevel@tonic-gate       }
12497c478bd9Sstevel@tonic-gate       if( pExpr->iColumn == OE_Rollback ||
12507c478bd9Sstevel@tonic-gate 	  pExpr->iColumn == OE_Abort ||
12517c478bd9Sstevel@tonic-gate 	  pExpr->iColumn == OE_Fail ){
12527c478bd9Sstevel@tonic-gate 	  sqliteVdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn,
12537c478bd9Sstevel@tonic-gate                            pExpr->token.z, pExpr->token.n);
12547c478bd9Sstevel@tonic-gate 	  sqliteVdbeDequoteP3(v, -1);
12557c478bd9Sstevel@tonic-gate       } else {
12567c478bd9Sstevel@tonic-gate 	  assert( pExpr->iColumn == OE_Ignore );
12577c478bd9Sstevel@tonic-gate 	  sqliteVdbeOp3(v, OP_Goto, 0, pParse->trigStack->ignoreJump,
12587c478bd9Sstevel@tonic-gate                            "(IGNORE jump)", 0);
12597c478bd9Sstevel@tonic-gate       }
12607c478bd9Sstevel@tonic-gate     }
12617c478bd9Sstevel@tonic-gate     break;
12627c478bd9Sstevel@tonic-gate   }
12637c478bd9Sstevel@tonic-gate }
12647c478bd9Sstevel@tonic-gate 
12657c478bd9Sstevel@tonic-gate /*
12667c478bd9Sstevel@tonic-gate ** Generate code that pushes the value of every element of the given
12677c478bd9Sstevel@tonic-gate ** expression list onto the stack.  If the includeTypes flag is true,
12687c478bd9Sstevel@tonic-gate ** then also push a string that is the datatype of each element onto
12697c478bd9Sstevel@tonic-gate ** the stack after the value.
12707c478bd9Sstevel@tonic-gate **
12717c478bd9Sstevel@tonic-gate ** Return the number of elements pushed onto the stack.
12727c478bd9Sstevel@tonic-gate */
sqliteExprCodeExprList(Parse * pParse,ExprList * pList,int includeTypes)12737c478bd9Sstevel@tonic-gate int sqliteExprCodeExprList(
12747c478bd9Sstevel@tonic-gate   Parse *pParse,     /* Parsing context */
12757c478bd9Sstevel@tonic-gate   ExprList *pList,   /* The expression list to be coded */
12767c478bd9Sstevel@tonic-gate   int includeTypes   /* TRUE to put datatypes on the stack too */
12777c478bd9Sstevel@tonic-gate ){
12787c478bd9Sstevel@tonic-gate   struct ExprList_item *pItem;
12797c478bd9Sstevel@tonic-gate   int i, n;
12807c478bd9Sstevel@tonic-gate   Vdbe *v;
12817c478bd9Sstevel@tonic-gate   if( pList==0 ) return 0;
12827c478bd9Sstevel@tonic-gate   v = sqliteGetVdbe(pParse);
12837c478bd9Sstevel@tonic-gate   n = pList->nExpr;
12847c478bd9Sstevel@tonic-gate   for(pItem=pList->a, i=0; i<n; i++, pItem++){
12857c478bd9Sstevel@tonic-gate     sqliteExprCode(pParse, pItem->pExpr);
12867c478bd9Sstevel@tonic-gate     if( includeTypes ){
1287*55fea89dSDan Cross       sqliteVdbeOp3(v, OP_String, 0, 0,
12887c478bd9Sstevel@tonic-gate          sqliteExprType(pItem->pExpr)==SQLITE_SO_NUM ? "numeric" : "text",
12897c478bd9Sstevel@tonic-gate          P3_STATIC);
12907c478bd9Sstevel@tonic-gate     }
12917c478bd9Sstevel@tonic-gate   }
12927c478bd9Sstevel@tonic-gate   return includeTypes ? n*2 : n;
12937c478bd9Sstevel@tonic-gate }
12947c478bd9Sstevel@tonic-gate 
12957c478bd9Sstevel@tonic-gate /*
12967c478bd9Sstevel@tonic-gate ** Generate code for a boolean expression such that a jump is made
12977c478bd9Sstevel@tonic-gate ** to the label "dest" if the expression is true but execution
12987c478bd9Sstevel@tonic-gate ** continues straight thru if the expression is false.
12997c478bd9Sstevel@tonic-gate **
13007c478bd9Sstevel@tonic-gate ** If the expression evaluates to NULL (neither true nor false), then
13017c478bd9Sstevel@tonic-gate ** take the jump if the jumpIfNull flag is true.
13027c478bd9Sstevel@tonic-gate */
sqliteExprIfTrue(Parse * pParse,Expr * pExpr,int dest,int jumpIfNull)13037c478bd9Sstevel@tonic-gate void sqliteExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
13047c478bd9Sstevel@tonic-gate   Vdbe *v = pParse->pVdbe;
13057c478bd9Sstevel@tonic-gate   int op = 0;
13067c478bd9Sstevel@tonic-gate   if( v==0 || pExpr==0 ) return;
13077c478bd9Sstevel@tonic-gate   switch( pExpr->op ){
13087c478bd9Sstevel@tonic-gate     case TK_LT:       op = OP_Lt;       break;
13097c478bd9Sstevel@tonic-gate     case TK_LE:       op = OP_Le;       break;
13107c478bd9Sstevel@tonic-gate     case TK_GT:       op = OP_Gt;       break;
13117c478bd9Sstevel@tonic-gate     case TK_GE:       op = OP_Ge;       break;
13127c478bd9Sstevel@tonic-gate     case TK_NE:       op = OP_Ne;       break;
13137c478bd9Sstevel@tonic-gate     case TK_EQ:       op = OP_Eq;       break;
13147c478bd9Sstevel@tonic-gate     case TK_ISNULL:   op = OP_IsNull;   break;
13157c478bd9Sstevel@tonic-gate     case TK_NOTNULL:  op = OP_NotNull;  break;
13167c478bd9Sstevel@tonic-gate     default:  break;
13177c478bd9Sstevel@tonic-gate   }
13187c478bd9Sstevel@tonic-gate   switch( pExpr->op ){
13197c478bd9Sstevel@tonic-gate     case TK_AND: {
13207c478bd9Sstevel@tonic-gate       int d2 = sqliteVdbeMakeLabel(v);
13217c478bd9Sstevel@tonic-gate       sqliteExprIfFalse(pParse, pExpr->pLeft, d2, !jumpIfNull);
13227c478bd9Sstevel@tonic-gate       sqliteExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
13237c478bd9Sstevel@tonic-gate       sqliteVdbeResolveLabel(v, d2);
13247c478bd9Sstevel@tonic-gate       break;
13257c478bd9Sstevel@tonic-gate     }
13267c478bd9Sstevel@tonic-gate     case TK_OR: {
13277c478bd9Sstevel@tonic-gate       sqliteExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
13287c478bd9Sstevel@tonic-gate       sqliteExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
13297c478bd9Sstevel@tonic-gate       break;
13307c478bd9Sstevel@tonic-gate     }
13317c478bd9Sstevel@tonic-gate     case TK_NOT: {
13327c478bd9Sstevel@tonic-gate       sqliteExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
13337c478bd9Sstevel@tonic-gate       break;
13347c478bd9Sstevel@tonic-gate     }
13357c478bd9Sstevel@tonic-gate     case TK_LT:
13367c478bd9Sstevel@tonic-gate     case TK_LE:
13377c478bd9Sstevel@tonic-gate     case TK_GT:
13387c478bd9Sstevel@tonic-gate     case TK_GE:
13397c478bd9Sstevel@tonic-gate     case TK_NE:
13407c478bd9Sstevel@tonic-gate     case TK_EQ: {
13417c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
13427c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pRight);
13437c478bd9Sstevel@tonic-gate       if( pParse->db->file_format>=4 && sqliteExprType(pExpr)==SQLITE_SO_TEXT ){
13447c478bd9Sstevel@tonic-gate         op += 6;  /* Convert numeric opcodes to text opcodes */
13457c478bd9Sstevel@tonic-gate       }
13467c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, op, jumpIfNull, dest);
13477c478bd9Sstevel@tonic-gate       break;
13487c478bd9Sstevel@tonic-gate     }
13497c478bd9Sstevel@tonic-gate     case TK_ISNULL:
13507c478bd9Sstevel@tonic-gate     case TK_NOTNULL: {
13517c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
13527c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, op, 1, dest);
13537c478bd9Sstevel@tonic-gate       break;
13547c478bd9Sstevel@tonic-gate     }
13557c478bd9Sstevel@tonic-gate     case TK_IN: {
13567c478bd9Sstevel@tonic-gate       int addr;
13577c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
13587c478bd9Sstevel@tonic-gate       addr = sqliteVdbeCurrentAddr(v);
13597c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_NotNull, -1, addr+3);
13607c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Pop, 1, 0);
13617c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Goto, 0, jumpIfNull ? dest : addr+4);
13627c478bd9Sstevel@tonic-gate       if( pExpr->pSelect ){
13637c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, dest);
13647c478bd9Sstevel@tonic-gate       }else{
13657c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, dest);
13667c478bd9Sstevel@tonic-gate       }
13677c478bd9Sstevel@tonic-gate       break;
13687c478bd9Sstevel@tonic-gate     }
13697c478bd9Sstevel@tonic-gate     case TK_BETWEEN: {
13707c478bd9Sstevel@tonic-gate       int addr;
13717c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
13727c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Dup, 0, 0);
13737c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pList->a[0].pExpr);
13747c478bd9Sstevel@tonic-gate       addr = sqliteVdbeAddOp(v, OP_Lt, !jumpIfNull, 0);
13757c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
13767c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Le, jumpIfNull, dest);
13777c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Integer, 0, 0);
13787c478bd9Sstevel@tonic-gate       sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
13797c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Pop, 1, 0);
13807c478bd9Sstevel@tonic-gate       break;
13817c478bd9Sstevel@tonic-gate     }
13827c478bd9Sstevel@tonic-gate     default: {
13837c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr);
13847c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_If, jumpIfNull, dest);
13857c478bd9Sstevel@tonic-gate       break;
13867c478bd9Sstevel@tonic-gate     }
13877c478bd9Sstevel@tonic-gate   }
13887c478bd9Sstevel@tonic-gate }
13897c478bd9Sstevel@tonic-gate 
13907c478bd9Sstevel@tonic-gate /*
13917c478bd9Sstevel@tonic-gate ** Generate code for a boolean expression such that a jump is made
13927c478bd9Sstevel@tonic-gate ** to the label "dest" if the expression is false but execution
13937c478bd9Sstevel@tonic-gate ** continues straight thru if the expression is true.
13947c478bd9Sstevel@tonic-gate **
13957c478bd9Sstevel@tonic-gate ** If the expression evaluates to NULL (neither true nor false) then
13967c478bd9Sstevel@tonic-gate ** jump if jumpIfNull is true or fall through if jumpIfNull is false.
13977c478bd9Sstevel@tonic-gate */
sqliteExprIfFalse(Parse * pParse,Expr * pExpr,int dest,int jumpIfNull)13987c478bd9Sstevel@tonic-gate void sqliteExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
13997c478bd9Sstevel@tonic-gate   Vdbe *v = pParse->pVdbe;
14007c478bd9Sstevel@tonic-gate   int op = 0;
14017c478bd9Sstevel@tonic-gate   if( v==0 || pExpr==0 ) return;
14027c478bd9Sstevel@tonic-gate   switch( pExpr->op ){
14037c478bd9Sstevel@tonic-gate     case TK_LT:       op = OP_Ge;       break;
14047c478bd9Sstevel@tonic-gate     case TK_LE:       op = OP_Gt;       break;
14057c478bd9Sstevel@tonic-gate     case TK_GT:       op = OP_Le;       break;
14067c478bd9Sstevel@tonic-gate     case TK_GE:       op = OP_Lt;       break;
14077c478bd9Sstevel@tonic-gate     case TK_NE:       op = OP_Eq;       break;
14087c478bd9Sstevel@tonic-gate     case TK_EQ:       op = OP_Ne;       break;
14097c478bd9Sstevel@tonic-gate     case TK_ISNULL:   op = OP_NotNull;  break;
14107c478bd9Sstevel@tonic-gate     case TK_NOTNULL:  op = OP_IsNull;   break;
14117c478bd9Sstevel@tonic-gate     default:  break;
14127c478bd9Sstevel@tonic-gate   }
14137c478bd9Sstevel@tonic-gate   switch( pExpr->op ){
14147c478bd9Sstevel@tonic-gate     case TK_AND: {
14157c478bd9Sstevel@tonic-gate       sqliteExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
14167c478bd9Sstevel@tonic-gate       sqliteExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
14177c478bd9Sstevel@tonic-gate       break;
14187c478bd9Sstevel@tonic-gate     }
14197c478bd9Sstevel@tonic-gate     case TK_OR: {
14207c478bd9Sstevel@tonic-gate       int d2 = sqliteVdbeMakeLabel(v);
14217c478bd9Sstevel@tonic-gate       sqliteExprIfTrue(pParse, pExpr->pLeft, d2, !jumpIfNull);
14227c478bd9Sstevel@tonic-gate       sqliteExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
14237c478bd9Sstevel@tonic-gate       sqliteVdbeResolveLabel(v, d2);
14247c478bd9Sstevel@tonic-gate       break;
14257c478bd9Sstevel@tonic-gate     }
14267c478bd9Sstevel@tonic-gate     case TK_NOT: {
14277c478bd9Sstevel@tonic-gate       sqliteExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
14287c478bd9Sstevel@tonic-gate       break;
14297c478bd9Sstevel@tonic-gate     }
14307c478bd9Sstevel@tonic-gate     case TK_LT:
14317c478bd9Sstevel@tonic-gate     case TK_LE:
14327c478bd9Sstevel@tonic-gate     case TK_GT:
14337c478bd9Sstevel@tonic-gate     case TK_GE:
14347c478bd9Sstevel@tonic-gate     case TK_NE:
14357c478bd9Sstevel@tonic-gate     case TK_EQ: {
14367c478bd9Sstevel@tonic-gate       if( pParse->db->file_format>=4 && sqliteExprType(pExpr)==SQLITE_SO_TEXT ){
14377c478bd9Sstevel@tonic-gate         /* Convert numeric comparison opcodes into text comparison opcodes.
14387c478bd9Sstevel@tonic-gate         ** This step depends on the fact that the text comparision opcodes are
14397c478bd9Sstevel@tonic-gate         ** always 6 greater than their corresponding numeric comparison
14407c478bd9Sstevel@tonic-gate         ** opcodes.
14417c478bd9Sstevel@tonic-gate         */
14427c478bd9Sstevel@tonic-gate         assert( OP_Eq+6 == OP_StrEq );
14437c478bd9Sstevel@tonic-gate         op += 6;
14447c478bd9Sstevel@tonic-gate       }
14457c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
14467c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pRight);
14477c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, op, jumpIfNull, dest);
14487c478bd9Sstevel@tonic-gate       break;
14497c478bd9Sstevel@tonic-gate     }
14507c478bd9Sstevel@tonic-gate     case TK_ISNULL:
14517c478bd9Sstevel@tonic-gate     case TK_NOTNULL: {
14527c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
14537c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, op, 1, dest);
14547c478bd9Sstevel@tonic-gate       break;
14557c478bd9Sstevel@tonic-gate     }
14567c478bd9Sstevel@tonic-gate     case TK_IN: {
14577c478bd9Sstevel@tonic-gate       int addr;
14587c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
14597c478bd9Sstevel@tonic-gate       addr = sqliteVdbeCurrentAddr(v);
14607c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_NotNull, -1, addr+3);
14617c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Pop, 1, 0);
14627c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Goto, 0, jumpIfNull ? dest : addr+4);
14637c478bd9Sstevel@tonic-gate       if( pExpr->pSelect ){
14647c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_NotFound, pExpr->iTable, dest);
14657c478bd9Sstevel@tonic-gate       }else{
14667c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_SetNotFound, pExpr->iTable, dest);
14677c478bd9Sstevel@tonic-gate       }
14687c478bd9Sstevel@tonic-gate       break;
14697c478bd9Sstevel@tonic-gate     }
14707c478bd9Sstevel@tonic-gate     case TK_BETWEEN: {
14717c478bd9Sstevel@tonic-gate       int addr;
14727c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pLeft);
14737c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Dup, 0, 0);
14747c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pList->a[0].pExpr);
14757c478bd9Sstevel@tonic-gate       addr = sqliteVdbeCurrentAddr(v);
14767c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Ge, !jumpIfNull, addr+3);
14777c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Pop, 1, 0);
14787c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Goto, 0, dest);
14797c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
14807c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Gt, jumpIfNull, dest);
14817c478bd9Sstevel@tonic-gate       break;
14827c478bd9Sstevel@tonic-gate     }
14837c478bd9Sstevel@tonic-gate     default: {
14847c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pExpr);
14857c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_IfNot, jumpIfNull, dest);
14867c478bd9Sstevel@tonic-gate       break;
14877c478bd9Sstevel@tonic-gate     }
14887c478bd9Sstevel@tonic-gate   }
14897c478bd9Sstevel@tonic-gate }
14907c478bd9Sstevel@tonic-gate 
14917c478bd9Sstevel@tonic-gate /*
14927c478bd9Sstevel@tonic-gate ** Do a deep comparison of two expression trees.  Return TRUE (non-zero)
14937c478bd9Sstevel@tonic-gate ** if they are identical and return FALSE if they differ in any way.
14947c478bd9Sstevel@tonic-gate */
sqliteExprCompare(Expr * pA,Expr * pB)14957c478bd9Sstevel@tonic-gate int sqliteExprCompare(Expr *pA, Expr *pB){
14967c478bd9Sstevel@tonic-gate   int i;
14977c478bd9Sstevel@tonic-gate   if( pA==0 ){
14987c478bd9Sstevel@tonic-gate     return pB==0;
14997c478bd9Sstevel@tonic-gate   }else if( pB==0 ){
15007c478bd9Sstevel@tonic-gate     return 0;
15017c478bd9Sstevel@tonic-gate   }
15027c478bd9Sstevel@tonic-gate   if( pA->op!=pB->op ) return 0;
15037c478bd9Sstevel@tonic-gate   if( !sqliteExprCompare(pA->pLeft, pB->pLeft) ) return 0;
15047c478bd9Sstevel@tonic-gate   if( !sqliteExprCompare(pA->pRight, pB->pRight) ) return 0;
15057c478bd9Sstevel@tonic-gate   if( pA->pList ){
15067c478bd9Sstevel@tonic-gate     if( pB->pList==0 ) return 0;
15077c478bd9Sstevel@tonic-gate     if( pA->pList->nExpr!=pB->pList->nExpr ) return 0;
15087c478bd9Sstevel@tonic-gate     for(i=0; i<pA->pList->nExpr; i++){
15097c478bd9Sstevel@tonic-gate       if( !sqliteExprCompare(pA->pList->a[i].pExpr, pB->pList->a[i].pExpr) ){
15107c478bd9Sstevel@tonic-gate         return 0;
15117c478bd9Sstevel@tonic-gate       }
15127c478bd9Sstevel@tonic-gate     }
15137c478bd9Sstevel@tonic-gate   }else if( pB->pList ){
15147c478bd9Sstevel@tonic-gate     return 0;
15157c478bd9Sstevel@tonic-gate   }
15167c478bd9Sstevel@tonic-gate   if( pA->pSelect || pB->pSelect ) return 0;
15177c478bd9Sstevel@tonic-gate   if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
15187c478bd9Sstevel@tonic-gate   if( pA->token.z ){
15197c478bd9Sstevel@tonic-gate     if( pB->token.z==0 ) return 0;
15207c478bd9Sstevel@tonic-gate     if( pB->token.n!=pA->token.n ) return 0;
15217c478bd9Sstevel@tonic-gate     if( sqliteStrNICmp(pA->token.z, pB->token.z, pB->token.n)!=0 ) return 0;
15227c478bd9Sstevel@tonic-gate   }
15237c478bd9Sstevel@tonic-gate   return 1;
15247c478bd9Sstevel@tonic-gate }
15257c478bd9Sstevel@tonic-gate 
15267c478bd9Sstevel@tonic-gate /*
15277c478bd9Sstevel@tonic-gate ** Add a new element to the pParse->aAgg[] array and return its index.
15287c478bd9Sstevel@tonic-gate */
appendAggInfo(Parse * pParse)15297c478bd9Sstevel@tonic-gate static int appendAggInfo(Parse *pParse){
15307c478bd9Sstevel@tonic-gate   if( (pParse->nAgg & 0x7)==0 ){
15317c478bd9Sstevel@tonic-gate     int amt = pParse->nAgg + 8;
15327c478bd9Sstevel@tonic-gate     AggExpr *aAgg = sqliteRealloc(pParse->aAgg, amt*sizeof(pParse->aAgg[0]));
15337c478bd9Sstevel@tonic-gate     if( aAgg==0 ){
15347c478bd9Sstevel@tonic-gate       return -1;
15357c478bd9Sstevel@tonic-gate     }
15367c478bd9Sstevel@tonic-gate     pParse->aAgg = aAgg;
15377c478bd9Sstevel@tonic-gate   }
15387c478bd9Sstevel@tonic-gate   memset(&pParse->aAgg[pParse->nAgg], 0, sizeof(pParse->aAgg[0]));
15397c478bd9Sstevel@tonic-gate   return pParse->nAgg++;
15407c478bd9Sstevel@tonic-gate }
15417c478bd9Sstevel@tonic-gate 
15427c478bd9Sstevel@tonic-gate /*
15437c478bd9Sstevel@tonic-gate ** Analyze the given expression looking for aggregate functions and
15447c478bd9Sstevel@tonic-gate ** for variables that need to be added to the pParse->aAgg[] array.
15457c478bd9Sstevel@tonic-gate ** Make additional entries to the pParse->aAgg[] array as necessary.
15467c478bd9Sstevel@tonic-gate **
15477c478bd9Sstevel@tonic-gate ** This routine should only be called after the expression has been
15487c478bd9Sstevel@tonic-gate ** analyzed by sqliteExprResolveIds() and sqliteExprCheck().
15497c478bd9Sstevel@tonic-gate **
15507c478bd9Sstevel@tonic-gate ** If errors are seen, leave an error message in zErrMsg and return
15517c478bd9Sstevel@tonic-gate ** the number of errors.
15527c478bd9Sstevel@tonic-gate */
sqliteExprAnalyzeAggregates(Parse * pParse,Expr * pExpr)15537c478bd9Sstevel@tonic-gate int sqliteExprAnalyzeAggregates(Parse *pParse, Expr *pExpr){
15547c478bd9Sstevel@tonic-gate   int i;
15557c478bd9Sstevel@tonic-gate   AggExpr *aAgg;
15567c478bd9Sstevel@tonic-gate   int nErr = 0;
15577c478bd9Sstevel@tonic-gate 
15587c478bd9Sstevel@tonic-gate   if( pExpr==0 ) return 0;
15597c478bd9Sstevel@tonic-gate   switch( pExpr->op ){
15607c478bd9Sstevel@tonic-gate     case TK_COLUMN: {
15617c478bd9Sstevel@tonic-gate       aAgg = pParse->aAgg;
15627c478bd9Sstevel@tonic-gate       for(i=0; i<pParse->nAgg; i++){
15637c478bd9Sstevel@tonic-gate         if( aAgg[i].isAgg ) continue;
15647c478bd9Sstevel@tonic-gate         if( aAgg[i].pExpr->iTable==pExpr->iTable
15657c478bd9Sstevel@tonic-gate          && aAgg[i].pExpr->iColumn==pExpr->iColumn ){
15667c478bd9Sstevel@tonic-gate           break;
15677c478bd9Sstevel@tonic-gate         }
15687c478bd9Sstevel@tonic-gate       }
15697c478bd9Sstevel@tonic-gate       if( i>=pParse->nAgg ){
15707c478bd9Sstevel@tonic-gate         i = appendAggInfo(pParse);
15717c478bd9Sstevel@tonic-gate         if( i<0 ) return 1;
15727c478bd9Sstevel@tonic-gate         pParse->aAgg[i].isAgg = 0;
15737c478bd9Sstevel@tonic-gate         pParse->aAgg[i].pExpr = pExpr;
15747c478bd9Sstevel@tonic-gate       }
15757c478bd9Sstevel@tonic-gate       pExpr->iAgg = i;
15767c478bd9Sstevel@tonic-gate       break;
15777c478bd9Sstevel@tonic-gate     }
15787c478bd9Sstevel@tonic-gate     case TK_AGG_FUNCTION: {
15797c478bd9Sstevel@tonic-gate       aAgg = pParse->aAgg;
15807c478bd9Sstevel@tonic-gate       for(i=0; i<pParse->nAgg; i++){
15817c478bd9Sstevel@tonic-gate         if( !aAgg[i].isAgg ) continue;
15827c478bd9Sstevel@tonic-gate         if( sqliteExprCompare(aAgg[i].pExpr, pExpr) ){
15837c478bd9Sstevel@tonic-gate           break;
15847c478bd9Sstevel@tonic-gate         }
15857c478bd9Sstevel@tonic-gate       }
15867c478bd9Sstevel@tonic-gate       if( i>=pParse->nAgg ){
15877c478bd9Sstevel@tonic-gate         i = appendAggInfo(pParse);
15887c478bd9Sstevel@tonic-gate         if( i<0 ) return 1;
15897c478bd9Sstevel@tonic-gate         pParse->aAgg[i].isAgg = 1;
15907c478bd9Sstevel@tonic-gate         pParse->aAgg[i].pExpr = pExpr;
15917c478bd9Sstevel@tonic-gate         pParse->aAgg[i].pFunc = sqliteFindFunction(pParse->db,
15927c478bd9Sstevel@tonic-gate              pExpr->token.z, pExpr->token.n,
15937c478bd9Sstevel@tonic-gate              pExpr->pList ? pExpr->pList->nExpr : 0, 0);
15947c478bd9Sstevel@tonic-gate       }
15957c478bd9Sstevel@tonic-gate       pExpr->iAgg = i;
15967c478bd9Sstevel@tonic-gate       break;
15977c478bd9Sstevel@tonic-gate     }
15987c478bd9Sstevel@tonic-gate     default: {
15997c478bd9Sstevel@tonic-gate       if( pExpr->pLeft ){
16007c478bd9Sstevel@tonic-gate         nErr = sqliteExprAnalyzeAggregates(pParse, pExpr->pLeft);
16017c478bd9Sstevel@tonic-gate       }
16027c478bd9Sstevel@tonic-gate       if( nErr==0 && pExpr->pRight ){
16037c478bd9Sstevel@tonic-gate         nErr = sqliteExprAnalyzeAggregates(pParse, pExpr->pRight);
16047c478bd9Sstevel@tonic-gate       }
16057c478bd9Sstevel@tonic-gate       if( nErr==0 && pExpr->pList ){
16067c478bd9Sstevel@tonic-gate         int n = pExpr->pList->nExpr;
16077c478bd9Sstevel@tonic-gate         int i;
16087c478bd9Sstevel@tonic-gate         for(i=0; nErr==0 && i<n; i++){
16097c478bd9Sstevel@tonic-gate           nErr = sqliteExprAnalyzeAggregates(pParse, pExpr->pList->a[i].pExpr);
16107c478bd9Sstevel@tonic-gate         }
16117c478bd9Sstevel@tonic-gate       }
16127c478bd9Sstevel@tonic-gate       break;
16137c478bd9Sstevel@tonic-gate     }
16147c478bd9Sstevel@tonic-gate   }
16157c478bd9Sstevel@tonic-gate   return nErr;
16167c478bd9Sstevel@tonic-gate }
16177c478bd9Sstevel@tonic-gate 
16187c478bd9Sstevel@tonic-gate /*
16197c478bd9Sstevel@tonic-gate ** Locate a user function given a name and a number of arguments.
16207c478bd9Sstevel@tonic-gate ** Return a pointer to the FuncDef structure that defines that
16217c478bd9Sstevel@tonic-gate ** function, or return NULL if the function does not exist.
16227c478bd9Sstevel@tonic-gate **
16237c478bd9Sstevel@tonic-gate ** If the createFlag argument is true, then a new (blank) FuncDef
16247c478bd9Sstevel@tonic-gate ** structure is created and liked into the "db" structure if a
16257c478bd9Sstevel@tonic-gate ** no matching function previously existed.  When createFlag is true
16267c478bd9Sstevel@tonic-gate ** and the nArg parameter is -1, then only a function that accepts
16277c478bd9Sstevel@tonic-gate ** any number of arguments will be returned.
16287c478bd9Sstevel@tonic-gate **
16297c478bd9Sstevel@tonic-gate ** If createFlag is false and nArg is -1, then the first valid
16307c478bd9Sstevel@tonic-gate ** function found is returned.  A function is valid if either xFunc
16317c478bd9Sstevel@tonic-gate ** or xStep is non-zero.
16327c478bd9Sstevel@tonic-gate */
sqliteFindFunction(sqlite * db,const char * zName,int nName,int nArg,int createFlag)16337c478bd9Sstevel@tonic-gate FuncDef *sqliteFindFunction(
16347c478bd9Sstevel@tonic-gate   sqlite *db,        /* An open database */
16357c478bd9Sstevel@tonic-gate   const char *zName, /* Name of the function.  Not null-terminated */
16367c478bd9Sstevel@tonic-gate   int nName,         /* Number of characters in the name */
16377c478bd9Sstevel@tonic-gate   int nArg,          /* Number of arguments.  -1 means any number */
16387c478bd9Sstevel@tonic-gate   int createFlag     /* Create new entry if true and does not otherwise exist */
16397c478bd9Sstevel@tonic-gate ){
16407c478bd9Sstevel@tonic-gate   FuncDef *pFirst, *p, *pMaybe;
16417c478bd9Sstevel@tonic-gate   pFirst = p = (FuncDef*)sqliteHashFind(&db->aFunc, zName, nName);
16427c478bd9Sstevel@tonic-gate   if( p && !createFlag && nArg<0 ){
16437c478bd9Sstevel@tonic-gate     while( p && p->xFunc==0 && p->xStep==0 ){ p = p->pNext; }
16447c478bd9Sstevel@tonic-gate     return p;
16457c478bd9Sstevel@tonic-gate   }
16467c478bd9Sstevel@tonic-gate   pMaybe = 0;
16477c478bd9Sstevel@tonic-gate   while( p && p->nArg!=nArg ){
16487c478bd9Sstevel@tonic-gate     if( p->nArg<0 && !createFlag && (p->xFunc || p->xStep) ) pMaybe = p;
16497c478bd9Sstevel@tonic-gate     p = p->pNext;
16507c478bd9Sstevel@tonic-gate   }
16517c478bd9Sstevel@tonic-gate   if( p && !createFlag && p->xFunc==0 && p->xStep==0 ){
16527c478bd9Sstevel@tonic-gate     return 0;
16537c478bd9Sstevel@tonic-gate   }
16547c478bd9Sstevel@tonic-gate   if( p==0 && pMaybe ){
16557c478bd9Sstevel@tonic-gate     assert( createFlag==0 );
16567c478bd9Sstevel@tonic-gate     return pMaybe;
16577c478bd9Sstevel@tonic-gate   }
16587c478bd9Sstevel@tonic-gate   if( p==0 && createFlag && (p = sqliteMalloc(sizeof(*p)))!=0 ){
16597c478bd9Sstevel@tonic-gate     p->nArg = nArg;
16607c478bd9Sstevel@tonic-gate     p->pNext = pFirst;
16617c478bd9Sstevel@tonic-gate     p->dataType = pFirst ? pFirst->dataType : SQLITE_NUMERIC;
16627c478bd9Sstevel@tonic-gate     sqliteHashInsert(&db->aFunc, zName, nName, (void*)p);
16637c478bd9Sstevel@tonic-gate   }
16647c478bd9Sstevel@tonic-gate   return p;
16657c478bd9Sstevel@tonic-gate }
1666