SQLite

Check-in [b52dd82fe3]
Login

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

Overview
Comment::-) (CVS 56)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b52dd82fe32c38c999aef4f07d046d0428336965
User & Date: drh 2000-06-06 03:31:22.000
Context
2000-06-06
13:54
added IN and BETWEEN operators (CVS 57) (check-in: 54d198189b user: drh tags: trunk)
03:31
:-) (CVS 56) (check-in: b52dd82fe3 user: drh tags: trunk)
01:50
:-) (CVS 55) (check-in: bd8b2645cc user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/expr.c.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
** 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.
*/







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
** 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.
*/
175
176
177
178
179
180
181



182
183
184
185
186
187
188

    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.
        */







>
>
>







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

    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.
        */
224
225
226
227
228
229
230

231
232
233
234
235
236
237
              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.
      */







>







227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
              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.
      */
585
586
587
588
589
590
591

592
593
594
595
596
597
598
    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;
    }







>







589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
    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;
    }
675
676
677
678
679
680
681

682
683
684
685
686
687
688
    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;
    }







>







680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
    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
** 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







|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
** 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
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
*/
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;
}







|







472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
*/
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;
}
2889
2890
2891
2892
2893
2894
2895

2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912

2913
2914
2915
2916
2917
2918
2919
        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.
      */
      case OP_SetNotFound: {
        int i = pOp->p1;
        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);







>

















>







2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
        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.
      */
      case OP_SetNotFound: {
        int i = pOp->p1;
        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);