/ Check-in [b52dd82f]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment::-) (CVS 56)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b52dd82fe32c38c999aef4f07d046d0428336965
User & Date: drh 2000-06-06 03:31:22
Context
2000-06-06
13:54
added IN and BETWEEN operators (CVS 57) check-in: 54d19818 user: drh tags: trunk
03:31
:-) (CVS 56) check-in: b52dd82f user: drh tags: trunk
01:50
:-) (CVS 55) check-in: bd8b2645 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
175
176
177
178
179
180
181



182
183
184
185
186
187
188
...
224
225
226
227
228
229
230

231
232
233
234
235
236
237
...
585
586
587
588
589
590
591

592
593
594
595
596
597
598
...
675
676
677
678
679
680
681

682
683
684
685
686
687
688
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines used for processing expressions
**
** $Id: expr.c,v 1.7 2000/06/06 01:50:43 drh Exp $
*/
#include "sqliteInt.h"

/*
** Walk an expression tree.  Return 1 if the expression is constant
** and 0 if it involves variables.
*/
................................................................................

    case TK_IN: {
      Vdbe *v = pParse->pVdbe;
      if( v==0 ){
        v = pParse->pVdbe = sqliteVdbeCreate(pParse->db->pBe);
      }
      if( v==0 ) return 1;



      if( pExpr->pSelect ){
        /* Case 1:     expr IN (SELECT ...)
        **
        ** Generate code to write the results of the select into a temporary
        ** table.  The cursor number of the temporary table is stored in 
        ** iTable.
        */
................................................................................
              sqliteExprCode(pParse, pE2);
              sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0, 0, 0);
              break;
            }
          }
        }
      }

    }

    case TK_SELECT: {
      /* This has to be a scalar SELECT.  Generate code to put the
      ** value of this select in a memory cell and record the number
      ** of the memory cell in iField.
      */
................................................................................
    case TK_ISNULL:
    case TK_NOTNULL: {
      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
      break;
    }
    case TK_IN: {

      if( pExpr->pSelect ){
        sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, dest, 0, 0);
      }else{
        sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, dest, 0, 0);
      }
      break;
    }
................................................................................
    case TK_ISNULL:
    case TK_NOTNULL: {
      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
      break;
    }
    case TK_IN: {

      if( pExpr->pSelect ){
        sqliteVdbeAddOp(v, OP_NotFound, pExpr->iTable, dest, 0, 0);
      }else{
        sqliteVdbeAddOp(v, OP_SetNotFound, pExpr->iTable, dest, 0, 0);
      }
      break;
    }







|







 







>
>
>







 







>







 







>







 







>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
...
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
...
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines used for processing expressions
**
** $Id: expr.c,v 1.8 2000/06/06 03:31:22 drh Exp $
*/
#include "sqliteInt.h"

/*
** Walk an expression tree.  Return 1 if the expression is constant
** and 0 if it involves variables.
*/
................................................................................

    case TK_IN: {
      Vdbe *v = pParse->pVdbe;
      if( v==0 ){
        v = pParse->pVdbe = sqliteVdbeCreate(pParse->db->pBe);
      }
      if( v==0 ) return 1;
      if( sqliteExprResolveIds(pParse, pTabList, pExpr->pLeft) ){
        return 1;
      }
      if( pExpr->pSelect ){
        /* Case 1:     expr IN (SELECT ...)
        **
        ** Generate code to write the results of the select into a temporary
        ** table.  The cursor number of the temporary table is stored in 
        ** iTable.
        */
................................................................................
              sqliteExprCode(pParse, pE2);
              sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0, 0, 0);
              break;
            }
          }
        }
      }
      break;
    }

    case TK_SELECT: {
      /* This has to be a scalar SELECT.  Generate code to put the
      ** value of this select in a memory cell and record the number
      ** of the memory cell in iField.
      */
................................................................................
    case TK_ISNULL:
    case TK_NOTNULL: {
      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
      break;
    }
    case TK_IN: {
      sqliteExprCode(pParse, pExpr->pLeft);
      if( pExpr->pSelect ){
        sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, dest, 0, 0);
      }else{
        sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, dest, 0, 0);
      }
      break;
    }
................................................................................
    case TK_ISNULL:
    case TK_NOTNULL: {
      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
      break;
    }
    case TK_IN: {
      sqliteExprCode(pParse, pExpr->pLeft);
      if( pExpr->pSelect ){
        sqliteVdbeAddOp(v, OP_NotFound, pExpr->iTable, dest, 0, 0);
      }else{
        sqliteVdbeAddOp(v, OP_SetNotFound, pExpr->iTable, dest, 0, 0);
      }
      break;
    }

Changes to src/vdbe.c.

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
...
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
....
2889
2890
2891
2892
2893
2894
2895

2896
2897
2898
2899
2900
2901
2902
....
2906
2907
2908
2909
2910
2911
2912

2913
2914
2915
2916
2917
2918
2919
** inplicit conversion from one type to the other occurs as necessary.
** 
** Most of the code in this file is taken up by the sqliteVdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** $Id: vdbe.c,v 1.18 2000/06/06 01:50:43 drh Exp $
*/
#include "sqliteInt.h"
#include <unistd.h>

/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine.  Each instruction is an instance
................................................................................
*/
static void SetInsert(Set *p, char *zKey){
  SetElem *pElem;
  int h = sqliteHashNoCase(zKey, 0) % ArraySize(p->apHash);
  for(pElem=p->apHash[h]; pElem; pElem=pElem->pHash){
    if( strcmp(pElem->zKey, zKey)==0 ) return;
  }
  pElem = sqliteMalloc( sizeof(pElem) + strlen(zKey) );
  if( pElem==0 ) return;
  strcpy(pElem->zKey, zKey);
  pElem->pNext = p->pAll;
  p->pAll = pElem;
  pElem->pHash = p->apHash[h];
  p->apHash[h] = pElem;
}
................................................................................
        int tos = p->tos;
        if( tos<0 ) goto not_enough_stack;
        Stringify(p, tos);
        if( i>=0 && i<p->nSet && SetTest(&p->aSet[i], p->zStack[tos]) ){
          pc = pOp->p2 - 1;
        }
        PopStack(p, 1);

      }

      /* Opcode: SetNotFound P1 P2 *
      **
      ** Pop the stack once and compare the value popped off with the
      ** contents of set P1.  If the element popped does not exists in 
      ** set P1, then jump to P2.  Otherwise fall through.
................................................................................
        int tos = p->tos;
        if( tos<0 ) goto not_enough_stack;
        Stringify(p, tos);
        if( i>=0 && i<p->nSet && !SetTest(&p->aSet[i], p->zStack[tos]) ){
          pc = pOp->p2 - 1;
        }
        PopStack(p, 1);

      }

      /* An other opcode is illegal...
      */
      default: {
        sprintf(zBuf,"%d",pOp->opcode);
        sqliteSetString(pzErrMsg, "unknown opcode ", zBuf, 0);







|







 







|







 







>







 







>







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
...
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
....
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
....
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
** inplicit conversion from one type to the other occurs as necessary.
** 
** Most of the code in this file is taken up by the sqliteVdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** $Id: vdbe.c,v 1.19 2000/06/06 03:31:22 drh Exp $
*/
#include "sqliteInt.h"
#include <unistd.h>

/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine.  Each instruction is an instance
................................................................................
*/
static void SetInsert(Set *p, char *zKey){
  SetElem *pElem;
  int h = sqliteHashNoCase(zKey, 0) % ArraySize(p->apHash);
  for(pElem=p->apHash[h]; pElem; pElem=pElem->pHash){
    if( strcmp(pElem->zKey, zKey)==0 ) return;
  }
  pElem = sqliteMalloc( sizeof(*pElem) + strlen(zKey) );
  if( pElem==0 ) return;
  strcpy(pElem->zKey, zKey);
  pElem->pNext = p->pAll;
  p->pAll = pElem;
  pElem->pHash = p->apHash[h];
  p->apHash[h] = pElem;
}
................................................................................
        int tos = p->tos;
        if( tos<0 ) goto not_enough_stack;
        Stringify(p, tos);
        if( i>=0 && i<p->nSet && SetTest(&p->aSet[i], p->zStack[tos]) ){
          pc = pOp->p2 - 1;
        }
        PopStack(p, 1);
        break;
      }

      /* Opcode: SetNotFound P1 P2 *
      **
      ** Pop the stack once and compare the value popped off with the
      ** contents of set P1.  If the element popped does not exists in 
      ** set P1, then jump to P2.  Otherwise fall through.
................................................................................
        int tos = p->tos;
        if( tos<0 ) goto not_enough_stack;
        Stringify(p, tos);
        if( i>=0 && i<p->nSet && !SetTest(&p->aSet[i], p->zStack[tos]) ){
          pc = pOp->p2 - 1;
        }
        PopStack(p, 1);
        break;
      }

      /* An other opcode is illegal...
      */
      default: {
        sprintf(zBuf,"%d",pOp->opcode);
        sqliteSetString(pzErrMsg, "unknown opcode ", zBuf, 0);