xref: /sqlite-3.40.0/src/expr.c (revision 8be51133)
1cce7d176Sdrh /*
2cce7d176Sdrh ** Copyright (c) 1999, 2000 D. Richard Hipp
3cce7d176Sdrh **
4cce7d176Sdrh ** This program is free software; you can redistribute it and/or
5cce7d176Sdrh ** modify it under the terms of the GNU General Public
6cce7d176Sdrh ** License as published by the Free Software Foundation; either
7cce7d176Sdrh ** version 2 of the License, or (at your option) any later version.
8cce7d176Sdrh **
9cce7d176Sdrh ** This program is distributed in the hope that it will be useful,
10cce7d176Sdrh ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11cce7d176Sdrh ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12cce7d176Sdrh ** General Public License for more details.
13cce7d176Sdrh **
14cce7d176Sdrh ** You should have received a copy of the GNU General Public
15cce7d176Sdrh ** License along with this library; if not, write to the
16cce7d176Sdrh ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17cce7d176Sdrh ** Boston, MA  02111-1307, USA.
18cce7d176Sdrh **
19cce7d176Sdrh ** Author contact information:
20cce7d176Sdrh **   [email protected]
21cce7d176Sdrh **   http://www.hwaci.com/drh/
22cce7d176Sdrh **
23cce7d176Sdrh *************************************************************************
24cce7d176Sdrh ** This file contains C code routines used for processing expressions
25cce7d176Sdrh **
26*8be51133Sdrh ** $Id: expr.c,v 1.4 2000/06/03 19:19:41 drh Exp $
27cce7d176Sdrh */
28cce7d176Sdrh #include "sqliteInt.h"
29cce7d176Sdrh 
30cce7d176Sdrh /*
31cce7d176Sdrh ** This routine walks an expression tree and resolves references to
32cce7d176Sdrh ** table fields.  Nodes of the form ID.ID or ID resolve into an
33cce7d176Sdrh ** index to the table in the table list and a field offset.  The opcode
34cce7d176Sdrh ** for such nodes is changed to TK_FIELD.  The iTable value is changed
35cce7d176Sdrh ** to the index of the referenced table in pTabList, and the iField value
36cce7d176Sdrh ** is changed to the index of the field of the referenced table.
37cce7d176Sdrh **
38cce7d176Sdrh ** Unknown fields or tables provoke an error.  The function returns
39cce7d176Sdrh ** the number of errors seen and leaves an error message on pParse->zErrMsg.
40cce7d176Sdrh */
41cce7d176Sdrh int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
42cce7d176Sdrh   if( pExpr==0 ) return 0;
43cce7d176Sdrh   switch( pExpr->op ){
44cce7d176Sdrh     /* A lone identifier */
45cce7d176Sdrh     case TK_ID: {
46cce7d176Sdrh       int cnt = 0;   /* Number of matches */
47cce7d176Sdrh       int i;         /* Loop counter */
48cce7d176Sdrh       char *z = 0;
49cce7d176Sdrh       sqliteSetNString(&z, pExpr->token.z, pExpr->token.n, 0);
50cce7d176Sdrh       for(i=0; i<pTabList->nId; i++){
51cce7d176Sdrh         int j;
52cce7d176Sdrh         Table *pTab = pTabList->a[i].pTab;
53cce7d176Sdrh         if( pTab==0 ) continue;
54cce7d176Sdrh         for(j=0; j<pTab->nCol; j++){
557020f651Sdrh           if( sqliteStrICmp(pTab->aCol[j].zName, z)==0 ){
56cce7d176Sdrh             cnt++;
57cce7d176Sdrh             pExpr->iTable = i;
58cce7d176Sdrh             pExpr->iField = j;
59cce7d176Sdrh           }
60cce7d176Sdrh         }
61cce7d176Sdrh       }
62cce7d176Sdrh       sqliteFree(z);
63cce7d176Sdrh       if( cnt==0 ){
64cce7d176Sdrh         sqliteSetNString(&pParse->zErrMsg, "no such field: ", -1,
65cce7d176Sdrh           pExpr->token.z, pExpr->token.n, 0);
66cce7d176Sdrh         pParse->nErr++;
67cce7d176Sdrh         return 1;
68cce7d176Sdrh       }else if( cnt>1 ){
69cce7d176Sdrh         sqliteSetNString(&pParse->zErrMsg, "ambiguous field name: ", -1,
70cce7d176Sdrh           pExpr->token.z, pExpr->token.n, 0);
71cce7d176Sdrh         pParse->nErr++;
72cce7d176Sdrh         return 1;
73cce7d176Sdrh       }
74cce7d176Sdrh       pExpr->op = TK_FIELD;
75cce7d176Sdrh       break;
76cce7d176Sdrh     }
77cce7d176Sdrh 
78cce7d176Sdrh     /* A table name and field name:  ID.ID */
79cce7d176Sdrh     case TK_DOT: {
80cce7d176Sdrh       int cnt = 0;             /* Number of matches */
81cce7d176Sdrh       int i;                   /* Loop counter */
82cce7d176Sdrh       Expr *pLeft, *pRight;    /* Left and right subbranches of the expr */
83cce7d176Sdrh       char *zLeft, *zRight;    /* Text of an identifier */
84cce7d176Sdrh 
85cce7d176Sdrh       pLeft = pExpr->pLeft;
86cce7d176Sdrh       pRight = pExpr->pRight;
87cce7d176Sdrh       assert( pLeft && pLeft->op==TK_ID );
88cce7d176Sdrh       assert( pRight && pRight->op==TK_ID );
89cce7d176Sdrh       zLeft = 0;
90cce7d176Sdrh       sqliteSetNString(&zLeft, pLeft->token.z, pLeft->token.n, 0);
91cce7d176Sdrh       zRight = 0;
92cce7d176Sdrh       sqliteSetNString(&zRight, pRight->token.z, pRight->token.n, 0);
93cce7d176Sdrh       for(i=0; i<pTabList->nId; i++){
94cce7d176Sdrh         int j;
95cce7d176Sdrh         char *zTab;
96cce7d176Sdrh         Table *pTab = pTabList->a[i].pTab;
97cce7d176Sdrh         if( pTab==0 ) continue;
98cce7d176Sdrh         if( pTabList->a[i].zAlias ){
99cce7d176Sdrh           zTab = pTabList->a[i].zAlias;
100cce7d176Sdrh         }else{
101cce7d176Sdrh           zTab = pTab->zName;
102cce7d176Sdrh         }
103cce7d176Sdrh         if( sqliteStrICmp(zTab, zLeft)!=0 ) continue;
104cce7d176Sdrh         for(j=0; j<pTab->nCol; j++){
1057020f651Sdrh           if( sqliteStrICmp(pTab->aCol[j].zName, zRight)==0 ){
106cce7d176Sdrh             cnt++;
107cce7d176Sdrh             pExpr->iTable = i;
108cce7d176Sdrh             pExpr->iField = j;
109cce7d176Sdrh           }
110cce7d176Sdrh         }
111cce7d176Sdrh       }
112cce7d176Sdrh       sqliteFree(zLeft);
113cce7d176Sdrh       sqliteFree(zRight);
114cce7d176Sdrh       if( cnt==0 ){
115cce7d176Sdrh         sqliteSetNString(&pParse->zErrMsg, "no such field: ", -1,
116cce7d176Sdrh           pLeft->token.z, pLeft->token.n, ".", 1,
117cce7d176Sdrh           pRight->token.z, pRight->token.n, 0);
118cce7d176Sdrh         pParse->nErr++;
119cce7d176Sdrh         return 1;
120cce7d176Sdrh       }else if( cnt>1 ){
121cce7d176Sdrh         sqliteSetNString(&pParse->zErrMsg, "ambiguous field name: ", -1,
122cce7d176Sdrh           pLeft->token.z, pLeft->token.n, ".", 1,
123cce7d176Sdrh           pRight->token.z, pRight->token.n, 0);
124cce7d176Sdrh         pParse->nErr++;
125cce7d176Sdrh         return 1;
126cce7d176Sdrh       }
127cce7d176Sdrh       sqliteExprDelete(pLeft);
128cce7d176Sdrh       pExpr->pLeft = 0;
129cce7d176Sdrh       sqliteExprDelete(pRight);
130cce7d176Sdrh       pExpr->pRight = 0;
131cce7d176Sdrh       pExpr->op = TK_FIELD;
132cce7d176Sdrh       break;
133cce7d176Sdrh     }
134cce7d176Sdrh 
135cce7d176Sdrh     /* For all else, just recursively walk the tree */
136cce7d176Sdrh     default: {
137cce7d176Sdrh       if( pExpr->pLeft
138cce7d176Sdrh             && sqliteExprResolveIds(pParse, pTabList, pExpr->pLeft) ){
139cce7d176Sdrh         return 1;
140cce7d176Sdrh       }
141cce7d176Sdrh       if( pExpr->pRight
142cce7d176Sdrh             && sqliteExprResolveIds(pParse, pTabList, pExpr->pRight) ){
143cce7d176Sdrh         return 1;
144cce7d176Sdrh       }
145cce7d176Sdrh       if( pExpr->pList ){
146cce7d176Sdrh         int i;
147cce7d176Sdrh         ExprList *pList = pExpr->pList;
148cce7d176Sdrh         for(i=0; i<pList->nExpr; i++){
149cce7d176Sdrh           if( sqliteExprResolveIds(pParse, pTabList, pList->a[i].pExpr) ){
150cce7d176Sdrh             return 1;
151cce7d176Sdrh           }
152cce7d176Sdrh         }
153cce7d176Sdrh       }
154cce7d176Sdrh     }
155cce7d176Sdrh   }
156cce7d176Sdrh   return 0;
157cce7d176Sdrh }
158cce7d176Sdrh 
159cce7d176Sdrh #if 0 /* NOT USED */
160cce7d176Sdrh /*
161cce7d176Sdrh ** Compare a token against a string.  Return TRUE if they match.
162cce7d176Sdrh */
163cce7d176Sdrh static int sqliteTokenCmp(Token *pToken, const char *zStr){
164cce7d176Sdrh   int n = strlen(zStr);
165cce7d176Sdrh   if( n!=pToken->n ) return 0;
166cce7d176Sdrh   return sqliteStrNICmp(pToken->z, zStr, n)==0;
167cce7d176Sdrh }
168cce7d176Sdrh #endif
169cce7d176Sdrh 
170cce7d176Sdrh /*
171cce7d176Sdrh ** Convert a function name into its integer identifier.  Return the
172cce7d176Sdrh ** identifier.  Return FN_Unknown if the function name is unknown.
173cce7d176Sdrh */
174cce7d176Sdrh int sqliteFuncId(Token *pToken){
175cce7d176Sdrh   static const struct {
176cce7d176Sdrh      char *zName;
177cce7d176Sdrh      int len;
178cce7d176Sdrh      int id;
179cce7d176Sdrh   } aFunc[] = {
180cce7d176Sdrh      { "count",  5, FN_Count },
181cce7d176Sdrh      { "min",    3, FN_Min   },
182cce7d176Sdrh      { "max",    3, FN_Max   },
183cce7d176Sdrh      { "sum",    3, FN_Sum   },
184cce7d176Sdrh   };
185cce7d176Sdrh   int i;
186cce7d176Sdrh   for(i=0; i<ArraySize(aFunc); i++){
187cce7d176Sdrh     if( aFunc[i].len==pToken->n
188cce7d176Sdrh      && sqliteStrNICmp(pToken->z, aFunc[i].zName, aFunc[i].len)==0 ){
189cce7d176Sdrh        return aFunc[i].id;
190cce7d176Sdrh     }
191cce7d176Sdrh   }
192cce7d176Sdrh   return FN_Unknown;
193cce7d176Sdrh }
194cce7d176Sdrh 
195cce7d176Sdrh /*
196cce7d176Sdrh ** Error check the functions in an expression.  Make sure all
197cce7d176Sdrh ** function names are recognized and all functions have the correct
198cce7d176Sdrh ** number of arguments.  Leave an error message in pParse->zErrMsg
199cce7d176Sdrh ** if anything is amiss.  Return the number of errors.
200cce7d176Sdrh **
201cce7d176Sdrh ** if pIsAgg is not null and this expression is an aggregate function
202cce7d176Sdrh ** (like count(*) or max(value)) then write a 1 into *pIsAgg.
203cce7d176Sdrh */
204cce7d176Sdrh int sqliteExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){
205cce7d176Sdrh   int nErr = 0;
206cce7d176Sdrh   if( pExpr==0 ) return 0;
207cce7d176Sdrh   if( pIsAgg ) *pIsAgg = 0;
208cce7d176Sdrh   switch( pExpr->op ){
209cce7d176Sdrh     case TK_FUNCTION: {
210cce7d176Sdrh       int id = sqliteFuncId(&pExpr->token);
211cce7d176Sdrh       int n = pExpr->pList ? pExpr->pList->nExpr : 0;
212cce7d176Sdrh       int no_such_func = 0;
213cce7d176Sdrh       int too_many_args = 0;
214cce7d176Sdrh       int too_few_args = 0;
215cce7d176Sdrh       int is_agg = 0;
216cce7d176Sdrh       int i;
217cce7d176Sdrh       switch( id ){
218cce7d176Sdrh         case FN_Unknown: {
219cce7d176Sdrh           no_such_func = 1;
220cce7d176Sdrh           break;
221cce7d176Sdrh         }
222cce7d176Sdrh         case FN_Count: {
223cce7d176Sdrh           no_such_func = !allowAgg;
224cce7d176Sdrh           too_many_args = n>1;
225cce7d176Sdrh           is_agg = 1;
226cce7d176Sdrh           break;
227cce7d176Sdrh         }
228cce7d176Sdrh         case FN_Max:
229cce7d176Sdrh         case FN_Min: {
230cce7d176Sdrh           too_few_args = allowAgg ? n<1 : n<2;
231cce7d176Sdrh           is_agg = n==1;
232cce7d176Sdrh           break;
233cce7d176Sdrh         }
234cce7d176Sdrh         case FN_Sum: {
235cce7d176Sdrh           no_such_func = !allowAgg;
236cce7d176Sdrh           too_many_args = n>1;
237cce7d176Sdrh           too_few_args = n<1;
238cce7d176Sdrh           is_agg = 1;
239cce7d176Sdrh           break;
240cce7d176Sdrh         }
241cce7d176Sdrh         default: break;
242cce7d176Sdrh       }
243cce7d176Sdrh       if( no_such_func ){
244cce7d176Sdrh         sqliteSetNString(&pParse->zErrMsg, "no such function: ", -1,
245cce7d176Sdrh            pExpr->token.z, pExpr->token.n, 0);
246cce7d176Sdrh         pParse->nErr++;
247cce7d176Sdrh         nErr++;
248cce7d176Sdrh       }else if( too_many_args ){
249cce7d176Sdrh         sqliteSetNString(&pParse->zErrMsg, "too many arguments to function ",-1,
250cce7d176Sdrh            pExpr->token.z, pExpr->token.n, "()", 2, 0);
251cce7d176Sdrh         pParse->nErr++;
252cce7d176Sdrh         nErr++;
253cce7d176Sdrh       }else if( too_few_args ){
254cce7d176Sdrh         sqliteSetNString(&pParse->zErrMsg, "too few arguments to function ",-1,
255cce7d176Sdrh            pExpr->token.z, pExpr->token.n, "()", 2, 0);
256cce7d176Sdrh         pParse->nErr++;
257cce7d176Sdrh         nErr++;
258cce7d176Sdrh       }
259cce7d176Sdrh       if( is_agg && pIsAgg ) *pIsAgg = 1;
260cce7d176Sdrh       for(i=0; nErr==0 && i<n; i++){
261cce7d176Sdrh         nErr = sqliteExprCheck(pParse, pExpr->pList->a[i].pExpr, 0, 0);
262cce7d176Sdrh       }
263cce7d176Sdrh     }
264cce7d176Sdrh     default: {
265cce7d176Sdrh       if( pExpr->pLeft ){
266cce7d176Sdrh         nErr = sqliteExprCheck(pParse, pExpr->pLeft, 0, 0);
267cce7d176Sdrh       }
268cce7d176Sdrh       if( nErr==0 && pExpr->pRight ){
269cce7d176Sdrh         nErr = sqliteExprCheck(pParse, pExpr->pRight, 0, 0);
270cce7d176Sdrh       }
271cce7d176Sdrh       break;
272cce7d176Sdrh     }
273cce7d176Sdrh   }
274cce7d176Sdrh   return nErr;
275cce7d176Sdrh }
276cce7d176Sdrh 
277cce7d176Sdrh /*
278cce7d176Sdrh ** Generate code into the current Vdbe to evaluate the given
279cce7d176Sdrh ** expression and leave the result on the stack.
280cce7d176Sdrh */
281cce7d176Sdrh void sqliteExprCode(Parse *pParse, Expr *pExpr){
282cce7d176Sdrh   Vdbe *v = pParse->pVdbe;
283cce7d176Sdrh   int op;
284cce7d176Sdrh   switch( pExpr->op ){
285cce7d176Sdrh     case TK_PLUS:     op = OP_Add;      break;
286cce7d176Sdrh     case TK_MINUS:    op = OP_Subtract; break;
287cce7d176Sdrh     case TK_STAR:     op = OP_Multiply; break;
288cce7d176Sdrh     case TK_SLASH:    op = OP_Divide;   break;
289cce7d176Sdrh     case TK_AND:      op = OP_And;      break;
290cce7d176Sdrh     case TK_OR:       op = OP_Or;       break;
291cce7d176Sdrh     case TK_LT:       op = OP_Lt;       break;
292cce7d176Sdrh     case TK_LE:       op = OP_Le;       break;
293cce7d176Sdrh     case TK_GT:       op = OP_Gt;       break;
294cce7d176Sdrh     case TK_GE:       op = OP_Ge;       break;
295cce7d176Sdrh     case TK_NE:       op = OP_Ne;       break;
296cce7d176Sdrh     case TK_EQ:       op = OP_Eq;       break;
297cce7d176Sdrh     case TK_LIKE:     op = OP_Like;     break;
298cce7d176Sdrh     case TK_GLOB:     op = OP_Glob;     break;
299cce7d176Sdrh     case TK_ISNULL:   op = OP_IsNull;   break;
300cce7d176Sdrh     case TK_NOTNULL:  op = OP_NotNull;  break;
301cce7d176Sdrh     case TK_NOT:      op = OP_Not;      break;
302cce7d176Sdrh     case TK_UMINUS:   op = OP_Negative; break;
303cce7d176Sdrh     default: break;
304cce7d176Sdrh   }
305cce7d176Sdrh   switch( pExpr->op ){
306cce7d176Sdrh     case TK_FIELD: {
307cce7d176Sdrh       sqliteVdbeAddOp(v, OP_Field, pExpr->iTable, pExpr->iField, 0, 0);
308cce7d176Sdrh       break;
309cce7d176Sdrh     }
310cce7d176Sdrh     case TK_INTEGER: {
311cce7d176Sdrh       int i = atoi(pExpr->token.z);
312cce7d176Sdrh       sqliteVdbeAddOp(v, OP_Integer, i, 0, 0, 0);
313cce7d176Sdrh       break;
314cce7d176Sdrh     }
315cce7d176Sdrh     case TK_FLOAT: {
316cce7d176Sdrh       int addr = sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0);
317cce7d176Sdrh       sqliteVdbeChangeP3(v, addr, pExpr->token.z, pExpr->token.n);
318cce7d176Sdrh       break;
319cce7d176Sdrh     }
320cce7d176Sdrh     case TK_STRING: {
321cce7d176Sdrh       int addr = sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0);
322cce7d176Sdrh       sqliteVdbeChangeP3(v, addr, pExpr->token.z, pExpr->token.n);
323cce7d176Sdrh       sqliteVdbeDequoteP3(v, addr);
324cce7d176Sdrh       break;
325cce7d176Sdrh     }
326cce7d176Sdrh     case TK_NULL: {
327cce7d176Sdrh       sqliteVdbeAddOp(v, OP_String, 0, 0, "", 0);
328cce7d176Sdrh       break;
329cce7d176Sdrh     }
330cce7d176Sdrh     case TK_AND:
331cce7d176Sdrh     case TK_OR:
332cce7d176Sdrh     case TK_PLUS:
333cce7d176Sdrh     case TK_STAR:
334cce7d176Sdrh     case TK_MINUS:
335cce7d176Sdrh     case TK_SLASH: {
336cce7d176Sdrh       sqliteExprCode(pParse, pExpr->pLeft);
337cce7d176Sdrh       sqliteExprCode(pParse, pExpr->pRight);
338cce7d176Sdrh       sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
339cce7d176Sdrh       break;
340cce7d176Sdrh     }
341cce7d176Sdrh     case TK_LT:
342cce7d176Sdrh     case TK_LE:
343cce7d176Sdrh     case TK_GT:
344cce7d176Sdrh     case TK_GE:
345cce7d176Sdrh     case TK_NE:
346cce7d176Sdrh     case TK_EQ:
347cce7d176Sdrh     case TK_LIKE:
348cce7d176Sdrh     case TK_GLOB: {
349cce7d176Sdrh       int dest;
350cce7d176Sdrh       sqliteVdbeAddOp(v, OP_Integer, 1, 0, 0, 0);
351cce7d176Sdrh       sqliteExprCode(pParse, pExpr->pLeft);
352cce7d176Sdrh       sqliteExprCode(pParse, pExpr->pRight);
353cce7d176Sdrh       dest = sqliteVdbeCurrentAddr(v) + 2;
354cce7d176Sdrh       sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
355cce7d176Sdrh       sqliteVdbeAddOp(v, OP_AddImm, -1, 0, 0, 0);
356cce7d176Sdrh       break;
357cce7d176Sdrh     }
358cce7d176Sdrh     case TK_NOT:
359cce7d176Sdrh     case TK_UMINUS: {
360cce7d176Sdrh       sqliteExprCode(pParse, pExpr->pLeft);
361cce7d176Sdrh       sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
362cce7d176Sdrh       break;
363cce7d176Sdrh     }
364cce7d176Sdrh     case TK_ISNULL:
365cce7d176Sdrh     case TK_NOTNULL: {
366cce7d176Sdrh       int dest;
367*8be51133Sdrh       sqliteVdbeAddOp(v, OP_Integer, 1, 0, 0, 0);
368cce7d176Sdrh       sqliteExprCode(pParse, pExpr->pLeft);
369cce7d176Sdrh       dest = sqliteVdbeCurrentAddr(v) + 2;
370cce7d176Sdrh       sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
371*8be51133Sdrh       sqliteVdbeAddOp(v, OP_AddImm, -1, 0, 0, 0);
372cce7d176Sdrh       break;
373cce7d176Sdrh     }
374cce7d176Sdrh     case TK_FUNCTION: {
375cce7d176Sdrh       int id = sqliteFuncId(&pExpr->token);
376cce7d176Sdrh       int op;
377cce7d176Sdrh       int i;
378cce7d176Sdrh       ExprList *pList = pExpr->pList;
379cce7d176Sdrh       op = id==FN_Min ? OP_Min : OP_Max;
380cce7d176Sdrh       for(i=0; i<pList->nExpr; i++){
381cce7d176Sdrh         sqliteExprCode(pParse, pList->a[i].pExpr);
382cce7d176Sdrh         if( i>0 ){
383cce7d176Sdrh           sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
384cce7d176Sdrh         }
385cce7d176Sdrh       }
386cce7d176Sdrh       break;
387cce7d176Sdrh     }
388cce7d176Sdrh   }
389cce7d176Sdrh   return;
390cce7d176Sdrh }
391cce7d176Sdrh 
392cce7d176Sdrh /*
393cce7d176Sdrh ** Generate code for a boolean expression such that a jump is made
394cce7d176Sdrh ** to the label "dest" if the expression is true but execution
395cce7d176Sdrh ** continues straight thru if the expression is false.
396cce7d176Sdrh */
397cce7d176Sdrh void sqliteExprIfTrue(Parse *pParse, Expr *pExpr, int dest){
398cce7d176Sdrh   Vdbe *v = pParse->pVdbe;
399cce7d176Sdrh   int op = 0;
400cce7d176Sdrh   switch( pExpr->op ){
401cce7d176Sdrh     case TK_LT:       op = OP_Lt;       break;
402cce7d176Sdrh     case TK_LE:       op = OP_Le;       break;
403cce7d176Sdrh     case TK_GT:       op = OP_Gt;       break;
404cce7d176Sdrh     case TK_GE:       op = OP_Ge;       break;
405cce7d176Sdrh     case TK_NE:       op = OP_Ne;       break;
406cce7d176Sdrh     case TK_EQ:       op = OP_Eq;       break;
407cce7d176Sdrh     case TK_LIKE:     op = OP_Like;     break;
408cce7d176Sdrh     case TK_GLOB:     op = OP_Glob;     break;
409cce7d176Sdrh     case TK_ISNULL:   op = OP_IsNull;   break;
410cce7d176Sdrh     case TK_NOTNULL:  op = OP_NotNull;  break;
411cce7d176Sdrh     default:  break;
412cce7d176Sdrh   }
413cce7d176Sdrh   switch( pExpr->op ){
414cce7d176Sdrh     case TK_AND: {
415cce7d176Sdrh       int d2 = sqliteVdbeMakeLabel(v);
416cce7d176Sdrh       sqliteExprIfFalse(pParse, pExpr->pLeft, d2);
417cce7d176Sdrh       sqliteExprIfTrue(pParse, pExpr->pRight, dest);
418cce7d176Sdrh       sqliteVdbeResolveLabel(v, d2);
419cce7d176Sdrh       break;
420cce7d176Sdrh     }
421cce7d176Sdrh     case TK_OR: {
422cce7d176Sdrh       sqliteExprIfTrue(pParse, pExpr->pLeft, dest);
423cce7d176Sdrh       sqliteExprIfTrue(pParse, pExpr->pRight, dest);
424cce7d176Sdrh       break;
425cce7d176Sdrh     }
426cce7d176Sdrh     case TK_NOT: {
427cce7d176Sdrh       sqliteExprIfFalse(pParse, pExpr->pLeft, dest);
428cce7d176Sdrh       break;
429cce7d176Sdrh     }
430cce7d176Sdrh     case TK_LT:
431cce7d176Sdrh     case TK_LE:
432cce7d176Sdrh     case TK_GT:
433cce7d176Sdrh     case TK_GE:
434cce7d176Sdrh     case TK_NE:
435cce7d176Sdrh     case TK_EQ:
436cce7d176Sdrh     case TK_LIKE:
437cce7d176Sdrh     case TK_GLOB: {
438cce7d176Sdrh       sqliteExprCode(pParse, pExpr->pLeft);
439cce7d176Sdrh       sqliteExprCode(pParse, pExpr->pRight);
440cce7d176Sdrh       sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
441cce7d176Sdrh       break;
442cce7d176Sdrh     }
443cce7d176Sdrh     case TK_ISNULL:
444cce7d176Sdrh     case TK_NOTNULL: {
445cce7d176Sdrh       sqliteExprCode(pParse, pExpr->pLeft);
446cce7d176Sdrh       sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
447cce7d176Sdrh       break;
448cce7d176Sdrh     }
449cce7d176Sdrh     default: {
450cce7d176Sdrh       sqliteExprCode(pParse, pExpr);
451cce7d176Sdrh       sqliteVdbeAddOp(v, OP_If, 0, dest, 0, 0);
452cce7d176Sdrh       break;
453cce7d176Sdrh     }
454cce7d176Sdrh   }
455cce7d176Sdrh }
456cce7d176Sdrh 
457cce7d176Sdrh /*
458cce7d176Sdrh ** Generate code for boolean expression such that a jump is made
459cce7d176Sdrh ** to the label "dest" if the expression is false but execution
460cce7d176Sdrh ** continues straight thru if the expression is true.
461cce7d176Sdrh */
462cce7d176Sdrh void sqliteExprIfFalse(Parse *pParse, Expr *pExpr, int dest){
463cce7d176Sdrh   Vdbe *v = pParse->pVdbe;
464cce7d176Sdrh   int op = 0;
465cce7d176Sdrh   switch( pExpr->op ){
466cce7d176Sdrh     case TK_LT:       op = OP_Ge;       break;
467cce7d176Sdrh     case TK_LE:       op = OP_Gt;       break;
468cce7d176Sdrh     case TK_GT:       op = OP_Le;       break;
469cce7d176Sdrh     case TK_GE:       op = OP_Lt;       break;
470cce7d176Sdrh     case TK_NE:       op = OP_Eq;       break;
471cce7d176Sdrh     case TK_EQ:       op = OP_Ne;       break;
472cce7d176Sdrh     case TK_LIKE:     op = OP_Like;     break;
473cce7d176Sdrh     case TK_GLOB:     op = OP_Glob;     break;
474cce7d176Sdrh     case TK_ISNULL:   op = OP_NotNull;  break;
475cce7d176Sdrh     case TK_NOTNULL:  op = OP_IsNull;   break;
476cce7d176Sdrh     default:  break;
477cce7d176Sdrh   }
478cce7d176Sdrh   switch( pExpr->op ){
479cce7d176Sdrh     case TK_AND: {
480cce7d176Sdrh       sqliteExprIfFalse(pParse, pExpr->pLeft, dest);
481cce7d176Sdrh       sqliteExprIfFalse(pParse, pExpr->pRight, dest);
482cce7d176Sdrh       break;
483cce7d176Sdrh     }
484cce7d176Sdrh     case TK_OR: {
485cce7d176Sdrh       int d2 = sqliteVdbeMakeLabel(v);
486cce7d176Sdrh       sqliteExprIfTrue(pParse, pExpr->pLeft, d2);
487cce7d176Sdrh       sqliteExprIfFalse(pParse, pExpr->pRight, dest);
488cce7d176Sdrh       sqliteVdbeResolveLabel(v, d2);
489cce7d176Sdrh       break;
490cce7d176Sdrh     }
491cce7d176Sdrh     case TK_NOT: {
492cce7d176Sdrh       sqliteExprIfTrue(pParse, pExpr->pLeft, dest);
493cce7d176Sdrh       break;
494cce7d176Sdrh     }
495cce7d176Sdrh     case TK_LT:
496cce7d176Sdrh     case TK_LE:
497cce7d176Sdrh     case TK_GT:
498cce7d176Sdrh     case TK_GE:
499cce7d176Sdrh     case TK_NE:
500cce7d176Sdrh     case TK_EQ: {
501cce7d176Sdrh       sqliteExprCode(pParse, pExpr->pLeft);
502cce7d176Sdrh       sqliteExprCode(pParse, pExpr->pRight);
503cce7d176Sdrh       sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
504cce7d176Sdrh       break;
505cce7d176Sdrh     }
506cce7d176Sdrh     case TK_LIKE:
507cce7d176Sdrh     case TK_GLOB: {
508cce7d176Sdrh       sqliteExprCode(pParse, pExpr->pLeft);
509cce7d176Sdrh       sqliteExprCode(pParse, pExpr->pRight);
510cce7d176Sdrh       sqliteVdbeAddOp(v, op, 1, dest, 0, 0);
511cce7d176Sdrh       break;
512cce7d176Sdrh     }
513cce7d176Sdrh     case TK_ISNULL:
514cce7d176Sdrh     case TK_NOTNULL: {
515cce7d176Sdrh       sqliteExprCode(pParse, pExpr->pLeft);
516cce7d176Sdrh       sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
517cce7d176Sdrh       break;
518cce7d176Sdrh     }
519cce7d176Sdrh     default: {
520cce7d176Sdrh       sqliteExprCode(pParse, pExpr);
521cce7d176Sdrh       sqliteVdbeAddOp(v, OP_Not, 0, 0, 0, 0);
522cce7d176Sdrh       sqliteVdbeAddOp(v, OP_If, 0, dest, 0, 0);
523cce7d176Sdrh       break;
524cce7d176Sdrh     }
525cce7d176Sdrh   }
526cce7d176Sdrh }
527