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