/ Check-in [912f47c7]
Login

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

Overview
Comment:The beginnings of changes to support pre-compiled SQL. Mostly untested, though all regression tests to pass. (CVS 1093)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 912f47c72d3597c6d5acff765d94922bd660339a
User & Date: drh 2003-09-06 01:10:47
Context
2003-09-06
20:12
Split almost 1300 lines of code out of vdbe.c into separate files vdbeInt.h and vdbeaux.c. (CVS 1094) check-in: bfd69391 user: drh tags: trunk
01:10
The beginnings of changes to support pre-compiled SQL. Mostly untested, though all regression tests to pass. (CVS 1093) check-in: 912f47c7 user: drh tags: trunk
2003-09-02
15:26
Add a logo from Rasmus Schultz. (CVS 1092) check-in: aaa84c62 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
306
307
308
309
310
311
312

313
314
315
316
317
318
319
...
910
911
912
913
914
915
916

917
918
919
920
921
922
923
....
1038
1039
1040
1041
1042
1043
1044




1045
1046
1047
1048
1049
1050
1051
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.98 2003/07/30 12:34:12 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Construct a new expression node and return a pointer to it.  Memory
** for this node is obtained from sqliteMalloc().  The calling function
................................................................................
    case TK_DOT:
    case TK_FUNCTION:
      return 0;
    case TK_NULL:
    case TK_STRING:
    case TK_INTEGER:
    case TK_FLOAT:

      return 1;
    default: {
      if( p->pLeft && !sqliteExprIsConstant(p->pLeft) ) return 0;
      if( p->pRight && !sqliteExprIsConstant(p->pRight) ) return 0;
      if( p->pList ){
        int i;
        for(i=0; i<p->pList->nExpr; i++){
................................................................................
    case TK_GLOB:
    case TK_LIKE:
      return SQLITE_SO_NUM;

    case TK_STRING:
    case TK_NULL:
    case TK_CONCAT:

      return SQLITE_SO_TEXT;

    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
................................................................................
      sqliteVdbeChangeP3(v, addr, pExpr->token.z, pExpr->token.n);
      sqliteVdbeDequoteP3(v, addr);
      break;
    }
    case TK_NULL: {
      sqliteVdbeAddOp(v, OP_String, 0, 0);
      break;




    }
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ: {







|







 







>







 







>







 







>
>
>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
...
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
....
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.99 2003/09/06 01:10:47 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Construct a new expression node and return a pointer to it.  Memory
** for this node is obtained from sqliteMalloc().  The calling function
................................................................................
    case TK_DOT:
    case TK_FUNCTION:
      return 0;
    case TK_NULL:
    case TK_STRING:
    case TK_INTEGER:
    case TK_FLOAT:
    case TK_VARIABLE:
      return 1;
    default: {
      if( p->pLeft && !sqliteExprIsConstant(p->pLeft) ) return 0;
      if( p->pRight && !sqliteExprIsConstant(p->pRight) ) return 0;
      if( p->pList ){
        int i;
        for(i=0; i<p->pList->nExpr; i++){
................................................................................
    case TK_GLOB:
    case TK_LIKE:
      return SQLITE_SO_NUM;

    case TK_STRING:
    case TK_NULL:
    case TK_CONCAT:
    case TK_VARIABLE:
      return SQLITE_SO_TEXT;

    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
................................................................................
      sqliteVdbeChangeP3(v, addr, pExpr->token.z, pExpr->token.n);
      sqliteVdbeDequoteP3(v, addr);
      break;
    }
    case TK_NULL: {
      sqliteVdbeAddOp(v, OP_String, 0, 0);
      break;
    }
    case TK_VARIABLE: {
      sqliteVdbeAddOp(v, OP_Variable, atoi(&pExpr->token.z[1]), 0);
      break;
    }
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ: {

Changes to src/func.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
537
538
539
540
541
542
543



544
545
546
547
548
549
550
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.30 2003/08/26 11:41:27 drh Exp $
*/
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "sqliteInt.h"
#include "os.h"
................................................................................
  if( p && p->z && p->z!=p->zBuf ){
    sqliteFree(p->z);
  }
}

/****************************************************************************
** Time and date functions.



**
** SQLite processes all times and dates as Julian Day numbers.  The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
** calendar system.
**
** This implement requires years to be expressed as a 4-digit number







|







 







>
>
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.31 2003/09/06 01:10:47 drh Exp $
*/
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "sqliteInt.h"
#include "os.h"
................................................................................
  if( p && p->z && p->z!=p->zBuf ){
    sqliteFree(p->z);
  }
}

/****************************************************************************
** Time and date functions.
**
** 1970-01-01 00:00:00 is JD 2440587.5.
** 2000-01-01 00:00:00 is JD 2451544.5
**
** SQLite processes all times and dates as Julian Day numbers.  The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
** calendar system.
**
** This implement requires years to be expressed as a 4-digit number

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
690
691
692
693
694
695
696


























697
698
699
700
701
702
703
...
712
713
714
715
716
717
718
719
720
721


722
723
724
725
726
727
728

729
730
731
732
733
734
735
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.140 2003/07/27 17:26:23 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................
  const char *zSql,           /* The SQL to be executed */
  const char **pzTail,        /* OUT: Next statement after the first */
  sqlite_vm **ppVm,           /* OUT: The virtual machine */
  char **pzErrMsg             /* OUT: Write error messages here */
){
  return sqliteMain(db, zSql, 0, 0, pzTail, ppVm, pzErrMsg);
}



























/*
** The following routine destroys a virtual machine that is created by
** the sqlite_compile() routine.
**
** The integer returned is an SQLITE_ success/failure code that describes
** the result of executing the virtual machine.  An error message is
................................................................................
){
  int rc = sqliteVdbeFinalize((Vdbe*)pVm, pzErrMsg);
  sqliteStrRealloc(pzErrMsg);
  return rc;
}

/*
** Destroy a virtual machine in the same manner as sqlite_finalize(). If 
** possible, leave *ppVm pointing at a new virtual machine which may be
** used to re-execute the query.


*/
int sqlite_reset(
  sqlite_vm *pVm,            /* The virtual machine to be destroyed */
  char **pzErrMsg,           /* OUT: Write error messages here */
  sqlite_vm **ppVm           /* OUT: The new virtual machine */
){
  int rc = sqliteVdbeReset((Vdbe*)pVm, pzErrMsg, (Vdbe **)ppVm);

  sqliteStrRealloc(pzErrMsg);
  return rc;
}

/*
** Return a static string that describes the kind of error specified in the
** argument.







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
|
>
>



|
<

|
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
...
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753

754
755
756
757
758
759
760
761
762
763
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.141 2003/09/06 01:10:47 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................
  const char *zSql,           /* The SQL to be executed */
  const char **pzTail,        /* OUT: Next statement after the first */
  sqlite_vm **ppVm,           /* OUT: The virtual machine */
  char **pzErrMsg             /* OUT: Write error messages here */
){
  return sqliteMain(db, zSql, 0, 0, pzTail, ppVm, pzErrMsg);
}

/*
** If the SQL that was handed to sqlite_compile contains variables of
** the form $1, $2, $3, etc. then this routine assigns values to those
** variables.  azValue[0] is assigned to $1.  azValue[1] is assigned
** to $2.  And so forth.  The value of variable $0 will always be NULL.
** The values of any variable $N where N>nValue will be NULL.  If any
** azValue[] is a NULL pointer, then the corresponding variable will be
** NULL.
**
** This routine can only be called immediately after sqlite_compile()
** or sqlite_reset() and before any calls to sqlite_step().
**
** This routine makes copies of all strings in azValue[] so the values
** passed in can be changed or deleted immediately after this call.  The
** copies are deallocated when sqlite_finalize() or sqlite_reset() is
** invoked.
*/
int sqlite_instantiate(
  sqlite_vm *pVm,
  int nValue,
  const char **azValue
){
  return sqliteVdbeSetVariables((Vdbe*)pVm, nValue, azValue);
}


/*
** The following routine destroys a virtual machine that is created by
** the sqlite_compile() routine.
**
** The integer returned is an SQLITE_ success/failure code that describes
** the result of executing the virtual machine.  An error message is
................................................................................
){
  int rc = sqliteVdbeFinalize((Vdbe*)pVm, pzErrMsg);
  sqliteStrRealloc(pzErrMsg);
  return rc;
}

/*
** Terminate the current execution of a virtual machine then
** reset the virtual machine back to its starting state so that it
** can be reused.  Any error message resulting from the prior execution
** is written into *pzErrMsg.  A success code from the prior execution
** is returned.
*/
int sqlite_reset(
  sqlite_vm *pVm,            /* The virtual machine to be destroyed */
  char **pzErrMsg            /* OUT: Write error messages here */

){
  int rc = sqliteVdbeReset((Vdbe*)pVm, pzErrMsg);
  sqliteVdbeMakeReady((Vdbe*)pVm, 0, 0, 0);
  sqliteStrRealloc(pzErrMsg);
  return rc;
}

/*
** Return a static string that describes the kind of error specified in the
** argument.

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
422
423
424
425
426
427
428




429
430
431
432
433
434
435
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.89 2003/08/26 11:41:27 drh Exp $
*/
#include "os.h"         /* Must be first to enable large file support */
#include "sqliteInt.h"
#include "pager.h"
#include <assert.h>
#include <string.h>

................................................................................
}

/*
** When this routine is called, the pager has the journal file open and
** a write lock on the database.  This routine releases the database
** write lock and acquires a read lock in its place.  The journal file
** is deleted and closed.




*/
static int pager_unwritelock(Pager *pPager){
  int rc;
  PgHdr *pPg;
  if( pPager->state<SQLITE_WRITELOCK ) return SQLITE_OK;
  sqlitepager_ckpt_commit(pPager);
  if( pPager->ckptOpen ){







|







 







>
>
>
>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.90 2003/09/06 01:10:47 drh Exp $
*/
#include "os.h"         /* Must be first to enable large file support */
#include "sqliteInt.h"
#include "pager.h"
#include <assert.h>
#include <string.h>

................................................................................
}

/*
** When this routine is called, the pager has the journal file open and
** a write lock on the database.  This routine releases the database
** write lock and acquires a read lock in its place.  The journal file
** is deleted and closed.
**
** TODO: Consider keeping the journal file open for temporary databases.
** This might give a performance improvement on windows where opening
** a file is an expensive operation.
*/
static int pager_unwritelock(Pager *pPager){
  int rc;
  PgHdr *pPg;
  if( pPager->state<SQLITE_WRITELOCK ) return SQLITE_OK;
  sqlitepager_ckpt_commit(pPager);
  if( pPager->ckptOpen ){

Changes to src/parse.y.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
537
538
539
540
541
542
543

544
545
546
547
548
549
550
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.99 2003/07/16 02:19:38 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  if( pParse->zErrMsg==0 ){
................................................................................
  A = sqliteExpr(TK_DOT, temp1, temp4, 0);
}
expr(A) ::= expr(B) ORACLE_OUTER_JOIN. 
                             {A = B; ExprSetProperty(A,EP_Oracle8Join);}
expr(A) ::= INTEGER(X).      {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
expr(A) ::= FLOAT(X).        {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
expr(A) ::= STRING(X).       {A = sqliteExpr(TK_STRING, 0, 0, &X);}

expr(A) ::= ID(X) LP exprlist(Y) RP(E). {
  A = sqliteExprFunction(Y, &X);
  sqliteExprSpan(A,&X,&E);
}
expr(A) ::= ID(X) LP STAR RP(E). {
  A = sqliteExprFunction(0, &X);
  sqliteExprSpan(A,&X,&E);







|







 







>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.100 2003/09/06 01:10:48 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  if( pParse->zErrMsg==0 ){
................................................................................
  A = sqliteExpr(TK_DOT, temp1, temp4, 0);
}
expr(A) ::= expr(B) ORACLE_OUTER_JOIN. 
                             {A = B; ExprSetProperty(A,EP_Oracle8Join);}
expr(A) ::= INTEGER(X).      {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
expr(A) ::= FLOAT(X).        {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
expr(A) ::= STRING(X).       {A = sqliteExpr(TK_STRING, 0, 0, &X);}
expr(A) ::= VARIABLE(X).     {A = sqliteExpr(TK_VARIABLE, 0, 0, &X);}
expr(A) ::= ID(X) LP exprlist(Y) RP(E). {
  A = sqliteExprFunction(Y, &X);
  sqliteExprSpan(A,&X,&E);
}
expr(A) ::= ID(X) LP STAR RP(E). {
  A = sqliteExprFunction(0, &X);
  sqliteExprSpan(A,&X,&E);

Changes to src/sqlite.h.in.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
691
692
693
694
695
696
697




















698
699
700



701
702
703
704
705
706
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.50 2003/07/22 09:24:44 danielk1977 Exp $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
**
** Additionally, if ppVm is not NULL, *ppVm is left pointing to a new virtual
** machine loaded with the compiled version of the original query ready for
** execution.
**
** If sqlite_reset() returns SQLITE_SCHEMA, then *ppVm is set to NULL.
**




















******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite_reset(sqlite_vm *, char **pzErrMsg, sqlite_vm **ppVm);




#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif

#endif /* _SQLITE_H_ */







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


<
>
>
>






8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719

720
721
722
723
724
725
726
727
728
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.51 2003/09/06 01:10:48 drh Exp $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
**
** Additionally, if ppVm is not NULL, *ppVm is left pointing to a new virtual
** machine loaded with the compiled version of the original query ready for
** execution.
**
** If sqlite_reset() returns SQLITE_SCHEMA, then *ppVm is set to NULL.
**
*/
int sqlite_reset(sqlite_vm *, char **pzErrMsg);

/*
** If the SQL that was handed to sqlite_compile contains variables of
** the form $1, $2, $3, etc. then this routine assigns values to those
** variables.  azValue[0] is assigned to $1.  azValue[1] is assigned
** to $2.  And so forth.  The value of variable $0 will always be NULL.
** The values of any variable $N where N>nValue will be NULL.  If any
** azValue[] is a NULL pointer, then the corresponding variable will be
** NULL.
**
** This routine can only be called immediately after sqlite_compile()
** or sqlite_reset() and before any calls to sqlite_step().
**
** This routine makes copies of all strings in azValue[] so the values
** passed in can be changed or deleted immediately after this call.  The
** copies are deallocated when sqlite_finalize() or sqlite_reset() is
** invoked.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/

int sqlite_instantiate(sqlite_vm*, int, const char**);



#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif

#endif /* _SQLITE_H_ */

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
769
770
771
772
773
774
775




























































776
777
778
779
780
781
782
...
823
824
825
826
827
828
829


830
831
832
833
834
835
836
837
838
839
840
841
842
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.26 2003/07/09 00:28:15 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
    sprintf(zBuf, "(%d) ", rc);
    Tcl_AppendResult(interp, zBuf, zErrMsg, 0);
    sqlite_freemem(zErrMsg);
    return TCL_ERROR;
  }
  return TCL_OK;
}





























































/*
** Usage:    breakpoint
**
** This routine exists for one purpose - to provide a place to put a
** breakpoint with GDB that can be triggered using TCL code.  The use
** for this is when a particular test fails on (say) the 1485th iteration.
................................................................................
#ifdef MEMORY_DEBUG
     { "sqlite_malloc_fail",             (Tcl_CmdProc*)sqlite_malloc_fail    },
     { "sqlite_malloc_stat",             (Tcl_CmdProc*)sqlite_malloc_stat    },
#endif
     { "sqlite_compile",                 (Tcl_CmdProc*)test_compile          },
     { "sqlite_step",                    (Tcl_CmdProc*)test_step             },
     { "sqlite_finalize",                (Tcl_CmdProc*)test_finalize         },


     { "breakpoint",                     (Tcl_CmdProc*)test_breakpoint       },
  };
  int i;

  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  Tcl_LinkVar(interp, "sqlite_search_count", 
      (char*)&sqlite_search_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_open_file_count", 
      (char*)&sqlite_open_file_count, TCL_LINK_INT);
  return TCL_OK;
}







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>













9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
...
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.27 2003/09/06 01:10:48 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
    sprintf(zBuf, "(%d) ", rc);
    Tcl_AppendResult(interp, zBuf, zErrMsg, 0);
    sqlite_freemem(zErrMsg);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:  sqlite_reset   VM 
**
** Reset a virtual machine and prepare it to be run again.
*/
static int test_reset(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  sqlite_vm *vm;
  int rc;
  char *zErrMsg = 0;
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
       " VM\"", 0);
    return TCL_ERROR;
  }
  if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR;
  rc = sqlite_reset(vm, &zErrMsg);
  if( rc ){
    char zBuf[50];
    sprintf(zBuf, "(%d) ", rc);
    Tcl_AppendResult(interp, zBuf, zErrMsg, 0);
    sqlite_freemem(zErrMsg);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:  sqlite_instantiate  VM  ARGS...
**
** Set the values of variables (ex: $1, $2, etc) in the original SQL string.
*/
static int test_instantiate(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  sqlite_vm *vm;
  int rc;
  if( argc<2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
       " VM ARGS...\"", 0);
    return TCL_ERROR;
  }
  if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR;
  rc = sqlite_instantiate(vm, argc-2, &argv[2]);
  if( rc ){
    char zBuf[50];
    sprintf(zBuf, "(%d) ", rc);
    Tcl_AppendResult(interp, zBuf, sqlite_error_string(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:    breakpoint
**
** This routine exists for one purpose - to provide a place to put a
** breakpoint with GDB that can be triggered using TCL code.  The use
** for this is when a particular test fails on (say) the 1485th iteration.
................................................................................
#ifdef MEMORY_DEBUG
     { "sqlite_malloc_fail",             (Tcl_CmdProc*)sqlite_malloc_fail    },
     { "sqlite_malloc_stat",             (Tcl_CmdProc*)sqlite_malloc_stat    },
#endif
     { "sqlite_compile",                 (Tcl_CmdProc*)test_compile          },
     { "sqlite_step",                    (Tcl_CmdProc*)test_step             },
     { "sqlite_finalize",                (Tcl_CmdProc*)test_finalize         },
     { "sqlite_instantiate",             (Tcl_CmdProc*)test_instantiate      },
     { "sqlite_reset",                   (Tcl_CmdProc*)test_reset            },
     { "breakpoint",                     (Tcl_CmdProc*)test_breakpoint       },
  };
  int i;

  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  Tcl_LinkVar(interp, "sqlite_search_count", 
      (char*)&sqlite_search_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_open_file_count", 
      (char*)&sqlite_open_file_count, TCL_LINK_INT);
  return TCL_OK;
}

Changes to src/tokenize.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
375
376
377
378
379
380
381






382
383
384
385
386
387
388
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.60 2003/05/04 18:30:59 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
      }
      return i;
    }
    case '[': {
      for(i=1; z[i] && z[i-1]!=']'; i++){}
      *tokenType = TK_ID;
      return i;






    }
    default: {
      if( !isIdChar[*z] ){
        break;
      }
      for(i=1; isIdChar[z[i]]; i++){}
      *tokenType = sqliteKeywordCode((char*)z, i);







|







 







>
>
>
>
>
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.61 2003/09/06 01:10:48 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
      }
      return i;
    }
    case '[': {
      for(i=1; z[i] && z[i-1]!=']'; i++){}
      *tokenType = TK_ID;
      return i;
    }
    case '$': {
      if( !isdigit(z[1]) ) break;
      for(i=1; z[i] && isdigit(z[i]); i++){}
      *tokenType = TK_VARIABLE;
      return i;
    }
    default: {
      if( !isIdChar[*z] ){
        break;
      }
      for(i=1; isIdChar[z[i]]; i++){}
      *tokenType = sqliteKeywordCode((char*)z, i);

Changes to src/vdbe.c.

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
266
267
268
269
270
271
272


273
274
275

276
277
278
279
280
281
282
....
1142
1143
1144
1145
1146
1147
1148









1149
1150
1151
1152
1153
1154

1155
1156
1157
1158
1159
1160
1161
....
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
....
1234
1235
1236
1237
1238
1239
1240

1241
1242
1243
1244
1245
1246
1247
....
1504
1505
1506
1507
1508
1509
1510

1511

1512
1513
1514
1515
1516
1517
1518
....
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
....
1767
1768
1769
1770
1771
1772
1773





















1774
1775
1776
1777
1778
1779
1780
....
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030








3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
....
5812
5813
5814
5815
5816
5817
5818
5819
5820



5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
....
5891
5892
5893
5894
5895
5896
5897

5898
















5899
5900
5901
5902
5903
5904
5905
5906












































5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
....
5924
5925
5926
5927
5928
5929
5930

**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.237 2003/08/26 11:35:00 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The makefile scans this source file and creates the following
................................................................................
  char **azColName;   /* Becomes the 4th parameter to callbacks */
  int nCursor;        /* Number of slots in aCsr[] */
  Cursor *aCsr;       /* One element of this array for each open cursor */
  Sorter *pSort;      /* A linked list of objects to be sorted */
  FILE *pFile;        /* At most one open file handler */
  int nField;         /* Number of file fields */
  char **azField;     /* Data for each file field */


  char *zLine;            /* A single line from the input file */
  int magic;              /* Magic number for sanity checking */
  int nLineAlloc;         /* Number of spaces allocated for zLine */

  int nMem;               /* Number of memory locations currently allocated */
  Mem *aMem;              /* The memory locations */
  Agg agg;                /* Aggregate information */
  int nSet;               /* Number of sets allocated */
  Set *aSet;              /* An array of sets */
  int nCallback;          /* Number of callbacks invoked so far */
  Keylist *pList;         /* A list of ROWIDs */
................................................................................
    Sorter *pSorter = p->pSort;
    p->pSort = pSorter->pNext;
    sqliteFree(pSorter->zKey);
    sqliteFree(pSorter->pData);
    sqliteFree(pSorter);
  }
}










/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open.

*/
static void Cleanup(Vdbe *p){
  int i;
  PopStack(p, p->tos+1);
  closeAllCursors(p);
  if( p->aMem ){
    for(i=0; i<p->nMem; i++){
................................................................................
    }
    sqliteFree(p->keylistStack);
    p->keylistStackDepth = 0;
    p->keylistStack = 0;
  }
  sqliteFree(p->zErrMsg);
  p->zErrMsg = 0;
  p->magic = VDBE_MAGIC_DEAD;
}

/*
** Delete an entire VDBE.
*/
void sqliteVdbeDelete(Vdbe *p){
  int i;
................................................................................
    if( p->aOp[i].p3type==P3_DYNAMIC ){
      sqliteFree(p->aOp[i].p3);
    }
  }
  sqliteFree(p->aOp);
  sqliteFree(p->aLabel);
  sqliteFree(p->aStack);

  sqliteFree(p);
}

/*
** Give a listing of the program in the virtual machine.
**
** The interface is the same as sqliteVdbeExec().  But instead of
................................................................................

  assert( p!=0 );
  assert( p->aStack==0 );
  assert( p->magic==VDBE_MAGIC_INIT );

  /* Add a HALT instruction to the very end of the program.
  */

  sqliteVdbeAddOp(p, OP_Halt, 0, 0);


  /* No instruction ever pushes more than a single element onto the
  ** stack.  And the stack never grows on successive executions of the
  ** same loop.  So the total number of instructions is an upper bound
  ** on the maximum stack depth required.
  **
  ** Allocation all the stack space we will ever need.
................................................................................
  p->uniqueCnt = 0;
  p->returnDepth = 0;
  p->errorAction = OE_Abort;
  p->undoTransOnError = 0;
  p->xCallback = xCallback;
  p->pCbArg = pCallbackArg;
  p->popStack =  0;
  p->explain = isExplain;
  p->magic = VDBE_MAGIC_RUN;
#ifdef VDBE_PROFILE
  for(i=0; i<p->nOp; i++){
    p->aOp[i].cnt = 0;
    p->aOp[i].cycles = 0;
  }
#endif
................................................................................
  }else{
    zStack[i] = z;
    aStack[i].n = strlen(z) + 1;
    aStack[i].flags = STK_Str | STK_Static;
  }
  break;
}






















/* Opcode: Pop P1 * *
**
** P1 elements are popped off of the top of stack and discarded.
*/
case OP_Pop: {
  assert( p->tos+1>=pOp->p1 );
................................................................................
**
** If P2 is not zero, then the original entries remain on the stack
** and the new key is pushed on top.  If P2 is zero, the original
** data is popped off the stack first then the new key is pushed
** back in its place.
**
** P3 is a string that is P1 characters long.  Each character is either
** an 'n' or a 't' to indicates if the argument should be numeric or
** text.  The first character corresponds to the lowest element on the
** stack.  If P3 is NULL then all arguments are assumed to be numeric.








**
** The key is a concatenation of fields.  Each field is terminated by
** a single 0x00 character.  A NULL field is introduced by an 'a' and
** is followed immediately by its 0x00 terminator.  A numeric field is
** introduced by a single character 'b' and is followed by a sequence
** of characters that represent the number such that a comparison of
** the character string using memcpy() sorts the numbers in numerical
** order.  The character strings for numbers are generated using the
** sqliteRealToSortable() function.  A text field is introduced by a
** 'c' character and is followed by the exact text of the field.  The
** use of an 'a', 'b', or 'c' character at the beginning of each field
** guarantees that NULL sort before numbers and that numbers sort
** before text.  0x00 characters do not occur except as separators
** between fields.
**
** See also: MakeIdxKey, SortMakeKey
*/
/* Opcode: MakeIdxKey P1 P2 P3
**
................................................................................
  rc = SQLITE_INTERNAL;
  goto vdbe_halt;
)
}


/*
** Clean up the VDBE after execution.  Return an integer which is the
** result code.



*/
int sqliteVdbeFinalize(Vdbe *p, char **pzErrMsg){
  sqlite *db = p->db;
  int i, rc;

  if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
    sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), 0);
    return SQLITE_MISUSE;
  }
  if( p->zErrMsg ){
    if( pzErrMsg && *pzErrMsg==0 ){
................................................................................
        );
        vdbePrintOp(out, i, &p->aOp[i]);
      }
      fclose(out);
    }
  }
#endif

  rc = p->rc;
















  sqliteVdbeDelete(p);
  if( db->want_to_close && db->pVdbe==0 ){
    sqlite_close(db);
  }
  return rc;
}

/*












































** Create a new Vdbe in *pOut and populate it with the program from p. Then
** pass p to sqliteVdbeFinalize().
*/
int sqliteVdbeReset(Vdbe *p, char ** pErrMsg, Vdbe** pOut)
{
  if( pOut && p->rc != SQLITE_SCHEMA ){

    /* Create a new VDBE and populate it with the program used by the old
    ** VDBE. Don't copy the last instruction of the program, as this is an 
    ** OP_Halt coded by sqliteVdbeMakeReady(). 
    */
    *pOut = sqliteVdbeCreate( p->db );
................................................................................
    p->nOp = 0;
    p->nOpAlloc = 0;
  }else if( pOut ){
    *pOut = NULL;
  }
  return sqliteVdbeFinalize(p, pErrMsg);
}








|







 







>
>

<

>







 







>
>
>
>
>
>
>
>
>





|
>







 







|







 







>







 







>
|
>







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
|
>
>
>
>
>
>
>
>











|







 







|
|
>
>
>

|

|







 







>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
<







 







>
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
266
267
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284
....
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
....
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
....
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
....
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
....
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
....
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
....
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
....
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
....
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018

6019
6020
6021
6022
6023
6024
6025
....
6031
6032
6033
6034
6035
6036
6037
6038
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.238 2003/09/06 01:10:48 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The makefile scans this source file and creates the following
................................................................................
  char **azColName;   /* Becomes the 4th parameter to callbacks */
  int nCursor;        /* Number of slots in aCsr[] */
  Cursor *aCsr;       /* One element of this array for each open cursor */
  Sorter *pSort;      /* A linked list of objects to be sorted */
  FILE *pFile;        /* At most one open file handler */
  int nField;         /* Number of file fields */
  char **azField;     /* Data for each file field */
  int nVariable;          /* Number of entries in azVariable[] */
  char **azVariable;      /* Values for the OP_Variable opcode */
  char *zLine;            /* A single line from the input file */

  int nLineAlloc;         /* Number of spaces allocated for zLine */
  int magic;              /* Magic number for sanity checking */
  int nMem;               /* Number of memory locations currently allocated */
  Mem *aMem;              /* The memory locations */
  Agg agg;                /* Aggregate information */
  int nSet;               /* Number of sets allocated */
  Set *aSet;              /* An array of sets */
  int nCallback;          /* Number of callbacks invoked so far */
  Keylist *pList;         /* A list of ROWIDs */
................................................................................
    Sorter *pSorter = p->pSort;
    p->pSort = pSorter->pNext;
    sqliteFree(pSorter->zKey);
    sqliteFree(pSorter->pData);
    sqliteFree(pSorter);
  }
}

/*
** Delete the variables in p->azVariable[]
*/
static void ClearVariableArray(Vdbe *p){
  sqliteFree(p->azVariable);
  p->nVariable = 0;
  p->azVariable = 0;
}

/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open.  It also deletes the values of
** variables in the azVariable[] array.
*/
static void Cleanup(Vdbe *p){
  int i;
  PopStack(p, p->tos+1);
  closeAllCursors(p);
  if( p->aMem ){
    for(i=0; i<p->nMem; i++){
................................................................................
    }
    sqliteFree(p->keylistStack);
    p->keylistStackDepth = 0;
    p->keylistStack = 0;
  }
  sqliteFree(p->zErrMsg);
  p->zErrMsg = 0;
  ClearVariableArray(p);
}

/*
** Delete an entire VDBE.
*/
void sqliteVdbeDelete(Vdbe *p){
  int i;
................................................................................
    if( p->aOp[i].p3type==P3_DYNAMIC ){
      sqliteFree(p->aOp[i].p3);
    }
  }
  sqliteFree(p->aOp);
  sqliteFree(p->aLabel);
  sqliteFree(p->aStack);
  p->magic = VDBE_MAGIC_DEAD;
  sqliteFree(p);
}

/*
** Give a listing of the program in the virtual machine.
**
** The interface is the same as sqliteVdbeExec().  But instead of
................................................................................

  assert( p!=0 );
  assert( p->aStack==0 );
  assert( p->magic==VDBE_MAGIC_INIT );

  /* Add a HALT instruction to the very end of the program.
  */
  if( p->nOp==0 || (p->aOp && p->aOp[p->nOp-1].opcode!=OP_Halt) ){
    sqliteVdbeAddOp(p, OP_Halt, 0, 0);
  }

  /* No instruction ever pushes more than a single element onto the
  ** stack.  And the stack never grows on successive executions of the
  ** same loop.  So the total number of instructions is an upper bound
  ** on the maximum stack depth required.
  **
  ** Allocation all the stack space we will ever need.
................................................................................
  p->uniqueCnt = 0;
  p->returnDepth = 0;
  p->errorAction = OE_Abort;
  p->undoTransOnError = 0;
  p->xCallback = xCallback;
  p->pCbArg = pCallbackArg;
  p->popStack =  0;
  p->explain |= isExplain;
  p->magic = VDBE_MAGIC_RUN;
#ifdef VDBE_PROFILE
  for(i=0; i<p->nOp; i++){
    p->aOp[i].cnt = 0;
    p->aOp[i].cycles = 0;
  }
#endif
................................................................................
  }else{
    zStack[i] = z;
    aStack[i].n = strlen(z) + 1;
    aStack[i].flags = STK_Str | STK_Static;
  }
  break;
}

/* Opcode: Variable P1 * *
**
** Push the value of variable P1 onto the stack.  A variable is
** an unknown in the original SQL string as handed to sqlite_compile().
** The first variable is $1, the second is $2, and so forth.  The
** value of the variables is determined by sqlite_instantiate().
*/
case OP_Variable: {
  int i = ++p->tos;
  if( pOp->p1>0 && pOp->p1<=p->nVariable && p->azVariable[pOp->p1-1]!=0 ){
    zStack[i] = p->azVariable[pOp->p1-1];
    aStack[i].n = strlen(zStack[i]) + 1;
    aStack[i].flags = STK_Str | STK_Static;
  }else{
    zStack[i] = 0;
    aStack[i].n = 0;
    aStack[i].flags = STK_Null;
  }
  break;
}

/* Opcode: Pop P1 * *
**
** P1 elements are popped off of the top of stack and discarded.
*/
case OP_Pop: {
  assert( p->tos+1>=pOp->p1 );
................................................................................
**
** If P2 is not zero, then the original entries remain on the stack
** and the new key is pushed on top.  If P2 is zero, the original
** data is popped off the stack first then the new key is pushed
** back in its place.
**
** P3 is a string that is P1 characters long.  Each character is either
** an 'n' or a 't' to indicates if the argument should be intepreted as
** numeric or text type.  The first character of P3 corresponds to the
** lowest element on the stack.  If P3 is NULL then all arguments are
** assumed to be of the numeric type.
**
** The type makes a difference in that text-type fields may not be 
** introduced by 'b' (as described in the next paragraph).  The
** first character of a text-type field must be either 'a' (if it is NULL)
** or 'c'.  Numeric fields will be introduced by 'b' if their content
** looks like a well-formed number.  Otherwise the 'a' or 'c' will be
** used.
**
** The key is a concatenation of fields.  Each field is terminated by
** a single 0x00 character.  A NULL field is introduced by an 'a' and
** is followed immediately by its 0x00 terminator.  A numeric field is
** introduced by a single character 'b' and is followed by a sequence
** of characters that represent the number such that a comparison of
** the character string using memcpy() sorts the numbers in numerical
** order.  The character strings for numbers are generated using the
** sqliteRealToSortable() function.  A text field is introduced by a
** 'c' character and is followed by the exact text of the field.  The
** use of an 'a', 'b', or 'c' character at the beginning of each field
** guarantees that NULLs sort before numbers and that numbers sort
** before text.  0x00 characters do not occur except as separators
** between fields.
**
** See also: MakeIdxKey, SortMakeKey
*/
/* Opcode: MakeIdxKey P1 P2 P3
**
................................................................................
  rc = SQLITE_INTERNAL;
  goto vdbe_halt;
)
}


/*
** Clean up a VDBE after execution but do not delete the VDBE just yet.
** Write any error messages into *pzErrMsg.  Return the result code.
**
** After this routine is run, the VDBE should be ready to be executed
** again.
*/
int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){
  sqlite *db = p->db;
  int i;

  if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
    sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), 0);
    return SQLITE_MISUSE;
  }
  if( p->zErrMsg ){
    if( pzErrMsg && *pzErrMsg==0 ){
................................................................................
        );
        vdbePrintOp(out, i, &p->aOp[i]);
      }
      fclose(out);
    }
  }
#endif
  p->magic = VDBE_MAGIC_INIT;
  return p->rc;
}

/*
** Clean up and delete a VDBE after execution.  Return an integer which is
** the result code.  Write any error message text into *pzErrMsg.
*/
int sqliteVdbeFinalize(Vdbe *p, char **pzErrMsg){
  int rc;
  sqlite *db;

  if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
    sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), 0);
    return SQLITE_MISUSE;
  }
  db = p->db;
  rc = sqliteVdbeReset(p, pzErrMsg);
  sqliteVdbeDelete(p);
  if( db->want_to_close && db->pVdbe==0 ){
    sqlite_close(db);
  }
  return rc;
}

/*
** Set the values of all variables.  Variable $1 in the original SQL will
** be the string azValue[0].  $2 will have the value azValue[1].  And
** so forth.  If a value is out of range (for example $3 when nValue==2)
** then its value will be NULL.
**
** This routine overrides any prior call.
*/
int sqliteVdbeSetVariables(Vdbe *p, int nValue, const char **azValue){
  int i, n;
  char *z;
  if( p->magic!=VDBE_MAGIC_RUN || p->pc!=0 || p->nVariable!=0 ){
    return SQLITE_MISUSE;
  }
  ClearVariableArray(p);
  if( nValue==0 ){
    p->nVariable = 0;
    p->azVariable = 0;
  }
  for(i=n=0; i<nValue; i++){
    if( azValue[i] ) n += strlen(azValue[i]) + 1;
  }
  p->azVariable = sqliteMalloc( sizeof(p->azVariable[0])*nValue + n );
  if( p->azVariable==0 ){
    p->nVariable = 0;
    return SQLITE_NOMEM;
  }
  z = (char*)&p->azVariable[nValue];
  for(i=0; i<nValue; i++){
    if( azValue[i]==0 ){
      p->azVariable[i] = 0;
    }else{
      p->azVariable[i] = z;
      n = strlen(azValue[i]);
      memcpy(z, azValue[i], n+1);
      z += n+1;
    }
  }
  p->nVariable = nValue;
  return SQLITE_OK;
}


#if 0
/*
** Create a new Vdbe in *pOut and populate it with the program from p. Then
** pass p to sqliteVdbeFinalize().
*/
int sqliteVdbeReset(Vdbe *p, char ** pErrMsg, Vdbe** pOut){

  if( pOut && p->rc != SQLITE_SCHEMA ){

    /* Create a new VDBE and populate it with the program used by the old
    ** VDBE. Don't copy the last instruction of the program, as this is an 
    ** OP_Halt coded by sqliteVdbeMakeReady(). 
    */
    *pOut = sqliteVdbeCreate( p->db );
................................................................................
    p->nOp = 0;
    p->nOpAlloc = 0;
  }else if( pOut ){
    *pOut = NULL;
  }
  return sqliteVdbeFinalize(p, pErrMsg);
}
#endif

Changes to src/vdbe.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
88
89
90
91
92
93
94
95

96
97
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.66 2003/07/22 09:24:44 danielk1977 Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
int sqliteVdbeExec(Vdbe*);
int sqliteVdbeList(Vdbe*);
int sqliteVdbeFinalize(Vdbe*,char**);
void sqliteVdbeResolveLabel(Vdbe*, int);
int sqliteVdbeCurrentAddr(Vdbe*);
void sqliteVdbeTrace(Vdbe*,FILE*);
void sqliteVdbeCompressSpace(Vdbe*,int);
int sqliteVdbeReset(Vdbe*,char **,Vdbe**);


#endif







|







 







|
>


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
88
89
90
91
92
93
94
95
96
97
98
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.67 2003/09/06 01:10:49 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
int sqliteVdbeExec(Vdbe*);
int sqliteVdbeList(Vdbe*);
int sqliteVdbeFinalize(Vdbe*,char**);
void sqliteVdbeResolveLabel(Vdbe*, int);
int sqliteVdbeCurrentAddr(Vdbe*);
void sqliteVdbeTrace(Vdbe*,FILE*);
void sqliteVdbeCompressSpace(Vdbe*,int);
int sqliteVdbeReset(Vdbe*,char **);
int sqliteVdbeSetVariables(Vdbe*,int,const char**);

#endif