/ Check-in [162b2591]
Login

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

Overview
Comment:The callback-free API is now working, though much more testing is need. (CVS 853)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:162b259188e6967fe9c3722da26b81aab5655d83
User & Date: drh 2003-01-29 14:06:08
Context
2003-01-29
18:46
Better error messages on constraint violations. Additional tests and bug fixes for the callback-free API. (CVS 854) check-in: ccc82f1a user: drh tags: trunk
14:06
The callback-free API is now working, though much more testing is need. (CVS 853) check-in: 162b2591 user: drh tags: trunk
2003-01-28
23:13
First code for the new callback-free API. All regression tests pass but the new API is mostly untested and is unlikely to work. (CVS 852) check-in: 065fa818 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
...
638
639
640
641
642
643
644

645
646
647
648
649
650
651
652
653
654

655
656
657
658
659
660
661
662
663
**
*************************************************************************
** 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.110 2003/01/28 23:13:12 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................
    }
  }
  if( db->file_format<3 ){
    sqliteSafetyOff(db);
    sqliteSetString(pzErrMsg, "obsolete database file format", 0);
    return SQLITE_ERROR;
  }
  if( db->recursionDepth==0 ){ db->nChange = 0; }
  db->recursionDepth++;
  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sParse.pBe = db->pBe;
  sParse.xCallback = xCallback;
  sParse.pArg = pArg;
  sParse.useCallback = ppVm==0;
#ifndef SQLITE_OMIT_TRACE
................................................................................
    sqliteSetString(pzErrMsg, "out of memory", 0);
    sParse.rc = SQLITE_NOMEM;
    sqliteBtreeRollback(db->pBe);
    if( db->pBeTemp ) sqliteBtreeRollback(db->pBeTemp);
    db->flags &= ~SQLITE_InTrans;
    sqliteResetInternalSchema(db);
  }

  if( sParse.rc!=SQLITE_OK && pzErrMsg && *pzErrMsg==0 ){
    sqliteSetString(pzErrMsg, sqlite_error_string(sParse.rc), 0);
  }
  sqliteStrRealloc(pzErrMsg);
  if( sParse.rc==SQLITE_SCHEMA ){
    sqliteResetInternalSchema(db);
  }
  db->recursionDepth--;
  if( sParse.useCallback==0 ){
    assert( ppVm );

    *ppVm = sParse.pVdbe;
    *pzTail = &sParse.sLastToken.z[sParse.sLastToken.n];
  }
  if( sqliteSafetyOff(db) ) goto exec_misuse;
  return sParse.rc;

exec_misuse:
  if( pzErrMsg ){
    *pzErrMsg = 0;







|







 







|
<







 







>







<


>
|
<







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
618
619
620
621
622
623
624
625

626
627
628
629
630
631
632
...
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651

652
653
654
655

656
657
658
659
660
661
662
**
*************************************************************************
** 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.111 2003/01/29 14:06:08 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................
    }
  }
  if( db->file_format<3 ){
    sqliteSafetyOff(db);
    sqliteSetString(pzErrMsg, "obsolete database file format", 0);
    return SQLITE_ERROR;
  }
  if( db->pVdbe==0 ){ db->nChange = 0; }

  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sParse.pBe = db->pBe;
  sParse.xCallback = xCallback;
  sParse.pArg = pArg;
  sParse.useCallback = ppVm==0;
#ifndef SQLITE_OMIT_TRACE
................................................................................
    sqliteSetString(pzErrMsg, "out of memory", 0);
    sParse.rc = SQLITE_NOMEM;
    sqliteBtreeRollback(db->pBe);
    if( db->pBeTemp ) sqliteBtreeRollback(db->pBeTemp);
    db->flags &= ~SQLITE_InTrans;
    sqliteResetInternalSchema(db);
  }
  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
  if( sParse.rc!=SQLITE_OK && pzErrMsg && *pzErrMsg==0 ){
    sqliteSetString(pzErrMsg, sqlite_error_string(sParse.rc), 0);
  }
  sqliteStrRealloc(pzErrMsg);
  if( sParse.rc==SQLITE_SCHEMA ){
    sqliteResetInternalSchema(db);
  }

  if( sParse.useCallback==0 ){
    assert( ppVm );
    *ppVm = (sqlite_vm*)sParse.pVdbe;
    *pzTail = sParse.zTail;

  }
  if( sqliteSafetyOff(db) ) goto exec_misuse;
  return sParse.rc;

exec_misuse:
  if( pzErrMsg ){
    *pzErrMsg = 0;

Changes to src/select.c.

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


701
702
703
704
705
706
707
....
1452
1453
1454
1455
1456
1457
1458

1459

1460
1461
1462
1463
1464
1465
1466
....
2302
2303
2304
2305
2306
2307
2308

2309

2310
2311
2312
2313
2314
2315
2316
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.123 2003/01/19 03:59:47 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
  Parse *pParse,      /* Parser context */
  int base,           /* VDBE cursor corresponding to first entry in pTabList */
  SrcList *pTabList,  /* List of tables */
  ExprList *pEList    /* Expressions defining the result set */
){
  Vdbe *v = pParse->pVdbe;
  int i;
  if( (pParse->db->flags & SQLITE_ReportTypes)==0 ) return;


  for(i=0; i<pEList->nExpr; i++){
    Expr *p = pEList->a[i].pExpr;
    char *zType = 0;
    if( p==0 ) continue;
    if( p->op==TK_COLUMN && pTabList ){
      Table *pTab = pTabList->a[p->iTable - base].pTab;
      int iCol = p->iColumn;
................................................................................
      selectOpName(p->op), " do not have the same number of result columns", 0);
    pParse->nErr++;
    return 1;
  }

  /* Issue a null callback if that is what the user wants.
  */

  if( (pParse->db->flags & SQLITE_NullCallback)!=0 && eDest==SRT_Callback ){

    sqliteVdbeAddOp(v, OP_NullCallback, p->pEList->nExpr, 0);
  }
  return 0;
}

/*
** Recursively scan through an expression tree.  For every reference
................................................................................
  if( pOrderBy ){
    generateSortTail(p, v, pEList->nExpr, eDest, iParm);
  }


  /* Issue a null callback if that is what the user wants.
  */

  if( (pParse->db->flags & SQLITE_NullCallback)!=0 && eDest==SRT_Callback ){

    sqliteVdbeAddOp(v, OP_NullCallback, pEList->nExpr, 0);
  }

  /* The SELECT was successfully coded.   Set the return code to 0
  ** to indicate no errors.
  */
  rc = 0;







|







 







|
>
>







 







>
|
>







 







>
|
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
....
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
....
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.124 2003/01/29 14:06:09 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
  Parse *pParse,      /* Parser context */
  int base,           /* VDBE cursor corresponding to first entry in pTabList */
  SrcList *pTabList,  /* List of tables */
  ExprList *pEList    /* Expressions defining the result set */
){
  Vdbe *v = pParse->pVdbe;
  int i;
  if( pParse->useCallback && (pParse->db->flags & SQLITE_ReportTypes)==0 ){
    return;
  }
  for(i=0; i<pEList->nExpr; i++){
    Expr *p = pEList->a[i].pExpr;
    char *zType = 0;
    if( p==0 ) continue;
    if( p->op==TK_COLUMN && pTabList ){
      Table *pTab = pTabList->a[p->iTable - base].pTab;
      int iCol = p->iColumn;
................................................................................
      selectOpName(p->op), " do not have the same number of result columns", 0);
    pParse->nErr++;
    return 1;
  }

  /* Issue a null callback if that is what the user wants.
  */
  if( eDest==SRT_Callback &&
    (pParse->useCallback==0 || (pParse->db->flags & SQLITE_NullCallback)!=0)
  ){
    sqliteVdbeAddOp(v, OP_NullCallback, p->pEList->nExpr, 0);
  }
  return 0;
}

/*
** Recursively scan through an expression tree.  For every reference
................................................................................
  if( pOrderBy ){
    generateSortTail(p, v, pEList->nExpr, eDest, iParm);
  }


  /* Issue a null callback if that is what the user wants.
  */
  if( eDest==SRT_Callback &&
    (pParse->useCallback==0 || (pParse->db->flags & SQLITE_NullCallback)!=0)
  ){
    sqliteVdbeAddOp(v, OP_NullCallback, pEList->nExpr, 0);
  }

  /* The SELECT was successfully coded.   Set the return code to 0
  ** to indicate no errors.
  */
  rc = 0;

Changes to src/sqlite.h.in.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
584
585
586
587
588
589
590


591
592
593
594
595
596
597
**    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.40 2003/01/28 23:13:12 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++.
................................................................................
**
** *pzTail is made to point to the first character past the end of the first
** SQL statement in zSql.  This routine only compiles the first statement
** in zSql, so *pzTail is left pointing to what remains uncompiled.
**
** *ppVm is left pointing to a "virtual machine" that can be used to execute
** the compiled statement.  Or if there is an error, *ppVm may be set to NULL.


**
** If any errors are detected during compilation, an error message is written
** into space obtained from malloc() and *pzErrMsg is made to point to that
** error message.  The calling routine is responsible for freeing the text
** of this message when it has finished with it.  Use sqlite_freemem() to
** free the message.  pzErrMsg may be NULL in which case no error message
** will be generated.







|







 







>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
**    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.41 2003/01/29 14:06:09 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++.
................................................................................
**
** *pzTail is made to point to the first character past the end of the first
** SQL statement in zSql.  This routine only compiles the first statement
** in zSql, so *pzTail is left pointing to what remains uncompiled.
**
** *ppVm is left pointing to a "virtual machine" that can be used to execute
** the compiled statement.  Or if there is an error, *ppVm may be set to NULL.
** If the input text contained no SQL (if the input is and empty string or
** a comment) then *ppVm is set to NULL.
**
** If any errors are detected during compilation, an error message is written
** into space obtained from malloc() and *pzErrMsg is made to point to that
** error message.  The calling routine is responsible for freeing the text
** of this message when it has finished with it.  Use sqlite_freemem() to
** free the message.  pzErrMsg may be NULL in which case no error message
** will be generated.

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
...
733
734
735
736
737
738
739

740
741
742
743
744
745
746
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.157 2003/01/28 23:13:12 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
................................................................................
  Hash aFunc;                   /* All functions that can be in SQL exprs */
  Hash aFKey;                   /* Foreign keys indexed by to-table */
  int lastRowid;                /* ROWID of most recent insert */
  int priorNewRowid;            /* Last randomly generated ROWID */
  int onError;                  /* Default conflict algorithm */
  int magic;                    /* Magic number for detect library misuse */
  int nChange;                  /* Number of rows changed */
  int recursionDepth;           /* Number of nested calls to sqlite_exec() */
#ifndef SQLITE_OMIT_TRACE
  void (*xTrace)(void*,const char*);     /* Trace function */
  void *pTraceArg;                       /* Argument to the trace function */
#endif
#ifndef SQLITE_OMIT_AUTHORIZATION
  int (*xAuth)(void*,int,const char*,const char*); /* Access Auth function */
  void *pAuthArg;               /* 1st argument to the access auth function */
................................................................................
  int rc;              /* Return code from execution */
  sqlite_callback xCallback;  /* The callback function */
  void *pArg;          /* First argument to the callback function */
  char *zErrMsg;       /* An error message */
  Token sErrToken;     /* The token at which the error occurred */
  Token sFirstToken;   /* The first token parsed */
  Token sLastToken;    /* The last token parsed */

  Table *pNewTable;    /* A table being constructed by CREATE TABLE */
  Vdbe *pVdbe;         /* An engine for executing database bytecode */
  u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */
  u8 explain;          /* True if the EXPLAIN flag is found on the query */
  u8 initFlag;         /* True if reparsing CREATE TABLEs */
  u8 nameClash;        /* A permanent table name clashes with temp table name */
  u8 useAgg;           /* If true, extract field values from the aggregator







|







 







|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
...
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.158 2003/01/29 14:06:09 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
................................................................................
  Hash aFunc;                   /* All functions that can be in SQL exprs */
  Hash aFKey;                   /* Foreign keys indexed by to-table */
  int lastRowid;                /* ROWID of most recent insert */
  int priorNewRowid;            /* Last randomly generated ROWID */
  int onError;                  /* Default conflict algorithm */
  int magic;                    /* Magic number for detect library misuse */
  int nChange;                  /* Number of rows changed */
  struct Vdbe *pVdbe;           /* List of active virtual machines */
#ifndef SQLITE_OMIT_TRACE
  void (*xTrace)(void*,const char*);     /* Trace function */
  void *pTraceArg;                       /* Argument to the trace function */
#endif
#ifndef SQLITE_OMIT_AUTHORIZATION
  int (*xAuth)(void*,int,const char*,const char*); /* Access Auth function */
  void *pAuthArg;               /* 1st argument to the access auth function */
................................................................................
  int rc;              /* Return code from execution */
  sqlite_callback xCallback;  /* The callback function */
  void *pArg;          /* First argument to the callback function */
  char *zErrMsg;       /* An error message */
  Token sErrToken;     /* The token at which the error occurred */
  Token sFirstToken;   /* The first token parsed */
  Token sLastToken;    /* The last token parsed */
  const char *zTail;   /* All SQL text past the last semicolon parsed */
  Table *pNewTable;    /* A table being constructed by CREATE TABLE */
  Vdbe *pVdbe;         /* An engine for executing database bytecode */
  u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */
  u8 explain;          /* True if the EXPLAIN flag is found on the query */
  u8 initFlag;         /* True if reparsing CREATE TABLEs */
  u8 nameClash;        /* A permanent table name clashes with temp table name */
  u8 useAgg;           /* If true, extract field values from the aggregator

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
729
730
731
732
733
734
735

736
737

738
739
740
741
742
743
744
...
761
762
763
764
765
766
767
768
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
...
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
**    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.17 2003/01/28 23:13:12 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
................................................................................
  if( rc ){
    assert( vm==0 );
    sprintf(zBuf, "(%d) ", rc);
    Tcl_AppendResult(interp, zBuf, zErr, 0);
    sqlite_freemem(zErr);
    return TCL_ERROR;
  }

  sprintf(zBuf, "%p", vm);
  Tcl_AppendResult(interp, zBuf, 0);

  Tcl_SetVar(interp, argv[3], zTail, 0);
  return TCL_OK;
}

/*
** Usage:  sqlite_step  VM  NVAR  VALUEVAR  COLNAMEVAR
**
................................................................................
  if( argc!=5 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
       " VM NVAR VALUEVAR COLNAMEVAR", 0);
    return TCL_ERROR;
  }
  if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR;
  rc = sqlite_step(vm, &N, &azValue, &azColName);
  if( rc==SQLITE_DONE || SQLITE_ROW ){
    sprintf(zBuf, "%d", N);
    Tcl_SetVar(interp, argv[2], zBuf, 0);
    Tcl_SetVar(interp, argv[3], "", 0);
    if( rc==SQLITE_ROW ){
      for(i=0; i<N; i++){
        Tcl_SetVar(interp, argv[3], azValue[i] ? azValue[i] : "",
            TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
      }
    }
    Tcl_SetVar(interp, argv[4], "", 0);
    for(i=0; i<N*2; i++){
      Tcl_SetVar(interp, argv[4], azValue[i] ? azValue[i] : "",
          TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
    }
  }
  switch( rc ){
    case SQLITE_DONE:   zRc = "SQLITE_DONE";    break;
    case SQLITE_BUSY:   zRc = "SQLITE_DONE";    break;
    case SQLITE_ROW:    zRc = "SQLITE_DONE";    break;
    case SQLITE_ERROR:  zRc = "SQLITE_DONE";    break;
    case SQLITE_MISUSE: zRc = "SQLITE_MISUSE";  break;
    default:            zRc = "unknown";        break;
  }
  Tcl_AppendResult(interp, zRc, 0);
  return TCL_OK;
}

................................................................................
  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 NVAR VALUEVAR COLNAMEVAR", 0);
    return TCL_ERROR;
  }
  if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR;
  rc = sqlite_finalize(vm, &zErrMsg);
  if( rc ){
    char zBuf[50];
    sprintf(zBuf, "(%d) ", rc);







|







 







>
|
|
>







 







|











|





|
|
|







 







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
...
763
764
765
766
767
768
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
...
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
**    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.18 2003/01/29 14:06:09 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
................................................................................
  if( rc ){
    assert( vm==0 );
    sprintf(zBuf, "(%d) ", rc);
    Tcl_AppendResult(interp, zBuf, zErr, 0);
    sqlite_freemem(zErr);
    return TCL_ERROR;
  }
  if( vm ){
    sprintf(zBuf, "%p", vm);
    Tcl_AppendResult(interp, zBuf, 0);
  }
  Tcl_SetVar(interp, argv[3], zTail, 0);
  return TCL_OK;
}

/*
** Usage:  sqlite_step  VM  NVAR  VALUEVAR  COLNAMEVAR
**
................................................................................
  if( argc!=5 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
       " VM NVAR VALUEVAR COLNAMEVAR", 0);
    return TCL_ERROR;
  }
  if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR;
  rc = sqlite_step(vm, &N, &azValue, &azColName);
  if( rc==SQLITE_DONE || rc==SQLITE_ROW ){
    sprintf(zBuf, "%d", N);
    Tcl_SetVar(interp, argv[2], zBuf, 0);
    Tcl_SetVar(interp, argv[3], "", 0);
    if( rc==SQLITE_ROW ){
      for(i=0; i<N; i++){
        Tcl_SetVar(interp, argv[3], azValue[i] ? azValue[i] : "",
            TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
      }
    }
    Tcl_SetVar(interp, argv[4], "", 0);
    for(i=0; i<N*2; i++){
      Tcl_SetVar(interp, argv[4], azColName[i] ? azColName[i] : "",
          TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
    }
  }
  switch( rc ){
    case SQLITE_DONE:   zRc = "SQLITE_DONE";    break;
    case SQLITE_BUSY:   zRc = "SQLITE_BUSY";    break;
    case SQLITE_ROW:    zRc = "SQLITE_ROW";     break;
    case SQLITE_ERROR:  zRc = "SQLITE_ERROR";   break;
    case SQLITE_MISUSE: zRc = "SQLITE_MISUSE";  break;
    default:            zRc = "unknown";        break;
  }
  Tcl_AppendResult(interp, zRc, 0);
  return TCL_OK;
}

................................................................................
  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_finalize(vm, &zErrMsg);
  if( rc ){
    char zBuf[50];
    sprintf(zBuf, "(%d) ", rc);

Changes to src/tokenize.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
418
419
420
421
422
423
424

425
426
427
428
429
430
431
...
441
442
443
444
445
446
447




448
449
450
451
452
453
454
...
455
456
457
458
459
460
461

462
463
464
465
466
467
468
*************************************************************************
** 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.54 2003/01/28 23:13:12 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
  i = 0;
  pEngine = sqliteParserAlloc((void*(*)(int))malloc);
  if( pEngine==0 ){
    sqliteSetString(pzErrMsg, "out of memory", 0);
    return 1;
  }
  pParse->sLastToken.dyn = 0;

  while( sqlite_malloc_failed==0 && zSql[i]!=0 ){
    
    assert( i>=0 );
    pParse->sLastToken.z = &zSql[i];
    assert( pParse->sLastToken.dyn==0 );
    pParse->sLastToken.n = sqliteGetToken((unsigned char*)&zSql[i], &tokenType);
    i += pParse->sLastToken.n;
................................................................................
      }
      case TK_ILLEGAL: {
        sqliteSetNString(pzErrMsg, "unrecognized token: \"", -1, 
           pParse->sLastToken.z, pParse->sLastToken.n, "\"", 1, 0);
        nErr++;
        goto abort_parse;
      }




      default: {
        sqliteParser(pEngine, tokenType, pParse->sLastToken, pParse);
        lastTokenParsed = tokenType;
        if( pParse->rc!=SQLITE_OK ){
          goto abort_parse;
        }
        break;
................................................................................
      }
    }
  }
abort_parse:
  if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
    if( lastTokenParsed!=TK_SEMI ){
      sqliteParser(pEngine, TK_SEMI, pParse->sLastToken, pParse);

    }
    sqliteParser(pEngine, 0, pParse->sLastToken, pParse);
  }
  sqliteParserFree(pEngine, free);
  if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
    sqliteSetString(&pParse->zErrMsg, sqlite_error_string(pParse->rc), 0);
  }







|







 







>







 







>
>
>
>







 







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
...
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
...
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
*************************************************************************
** 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.55 2003/01/29 14:06:09 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
  i = 0;
  pEngine = sqliteParserAlloc((void*(*)(int))malloc);
  if( pEngine==0 ){
    sqliteSetString(pzErrMsg, "out of memory", 0);
    return 1;
  }
  pParse->sLastToken.dyn = 0;
  pParse->zTail = zSql;
  while( sqlite_malloc_failed==0 && zSql[i]!=0 ){
    
    assert( i>=0 );
    pParse->sLastToken.z = &zSql[i];
    assert( pParse->sLastToken.dyn==0 );
    pParse->sLastToken.n = sqliteGetToken((unsigned char*)&zSql[i], &tokenType);
    i += pParse->sLastToken.n;
................................................................................
      }
      case TK_ILLEGAL: {
        sqliteSetNString(pzErrMsg, "unrecognized token: \"", -1, 
           pParse->sLastToken.z, pParse->sLastToken.n, "\"", 1, 0);
        nErr++;
        goto abort_parse;
      }
      case TK_SEMI: {
        pParse->zTail = &zSql[i];
        /* Fall thru into the default case */
      }
      default: {
        sqliteParser(pEngine, tokenType, pParse->sLastToken, pParse);
        lastTokenParsed = tokenType;
        if( pParse->rc!=SQLITE_OK ){
          goto abort_parse;
        }
        break;
................................................................................
      }
    }
  }
abort_parse:
  if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
    if( lastTokenParsed!=TK_SEMI ){
      sqliteParser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
      pParse->zTail = &zSql[i];
    }
    sqliteParser(pEngine, 0, pParse->sLastToken, pParse);
  }
  sqliteParserFree(pEngine, free);
  if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
    sqliteSetString(&pParse->zErrMsg, sqlite_error_string(pParse->rc), 0);
  }

Changes to src/util.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.56 2003/01/14 00:44:09 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
** sqlite.magic to SQLITE_MAGIC_ERROR.  This will cause a complete
** shutdown of the database.
**
** This routine is used to try to detect when API routines are called
** at the wrong time or in the wrong sequence.
*/
int sqliteSafetyCheck(sqlite *db){
  if( db->recursionDepth ){
    db->magic = SQLITE_MAGIC_ERROR;
    return 1;
  }
  return 0;
}







|







 







|





10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.57 2003/01/29 14:06:09 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
** sqlite.magic to SQLITE_MAGIC_ERROR.  This will cause a complete
** shutdown of the database.
**
** This routine is used to try to detect when API routines are called
** at the wrong time or in the wrong sequence.
*/
int sqliteSafetyCheck(sqlite *db){
  if( db->pVdbe!=0 ){
    db->magic = SQLITE_MAGIC_ERROR;
    return 1;
  }
  return 0;
}

Changes to src/vdbe.c.

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
238
239
240
241
242
243
244

245
246
247
248
249
250
251
...
312
313
314
315
316
317
318






319
320
321
322
323
324
325
...
759
760
761
762
763
764
765

766
767
768
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
....
1187
1188
1189
1190
1191
1192
1193










1194
1195
1196
1197
1198
1199
1200
....
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
....
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
....
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
....
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
....
1922
1923
1924
1925
1926
1927
1928

1929
1930
1931
1932
1933
1934
1935
....
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
**
** 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.200 2003/01/28 23:13:12 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The makefile scans this source file and creates the following
** array of string constants which are the names of all VDBE opcodes.
................................................................................
** state of the virtual machine.
**
** The "sqlite_vm" structure pointer that is returned by sqlite_compile()
** is really a pointer to an instance of this structure.
*/
struct Vdbe {
  sqlite *db;         /* The whole database */

  Btree *pBt;         /* Opaque context structure used by DB backend */
  FILE *trace;        /* Write an execution trace here, if not NULL */
  int nOp;            /* Number of instructions in the program */
  int nOpAlloc;       /* Number of slots allocated for aOp[] */
  Op *aOp;            /* Space to hold the virtual machine's program */
  int nLabel;         /* Number of labels used */
  int nLabelAlloc;    /* Number of slots allocated in aLabel[] */
................................................................................
*/
Vdbe *sqliteVdbeCreate(sqlite *db){
  Vdbe *p;
  p = sqliteMalloc( sizeof(Vdbe) );
  if( p==0 ) return 0;
  p->pBt = db->pBe;
  p->db = db;






  p->magic = VDBE_MAGIC_INIT;
  return p;
}

/*
** Turn tracing on or off
*/
................................................................................
int sqlite_step(
  sqlite_vm *pVm,              /* The virtual machine to execute */
  int *pN,                     /* OUT: Number of columns in result */
  const char ***pazValue,      /* OUT: Column data */
  const char ***pazColName     /* OUT: Column names and datatypes */
){
  Vdbe *p = (Vdbe*)pVm;

  int rc;

  if( p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_MISUSE;
  }




  if( p->explain ){
    rc = sqliteVdbeList(p);
  }else{
    rc = sqliteVdbeExec(p);
  }
  if( rc!=SQLITE_DONE ){
    *pazColName = (const char**)p->azColName;
    *pN = p->nResColumn;
  }else{
    *pN = 0;
    *pazColName = 0;
  }
  if( rc==SQLITE_ROW ){
    *pazValue = (const char**)p->azResColumn;
  }else{
    *pazValue = 0;



  }
  return rc;
}

/*
** Reset an Agg structure.  Delete all its contents. 
**
................................................................................
/*
** Delete an entire VDBE.
*/
void sqliteVdbeDelete(Vdbe *p){
  int i;
  if( p==0 ) return;
  Cleanup(p);










  if( p->nOpAlloc==0 ){
    p->aOp = 0;
    p->nOp = 0;
  }
  for(i=0; i<p->nOp; i++){
    if( p->aOp[i].p3type==P3_DYNAMIC ){
      sqliteFree(p->aOp[i].p3);
................................................................................
      p->zStack[4] = p->aOp[i].p3;
    }
    p->zStack[1] = sqliteOpcodeNames[p->aOp[i].opcode];
    if( p->xCallback==0 ){
      p->pc = i+1;
      p->azResColumn = p->zStack;
      p->nResColumn = 5;
      return SQLITE_CALLBACK;
    }
    if( sqliteSafetyOff(db) ){
      p->rc = SQLITE_MISUSE;
      break;
    }
    if( p->xCallback(p->pCbArg, 5, p->zStack, p->azColName) ){
      p->rc = SQLITE_ABORT;
................................................................................
** Prepare a virtual machine for execution.  This involves things such
** as allocating stack space and initializing the program counter.
** After the VDBE has be prepped, it can be executed by one or more
** calls to sqliteVdbeExec().  
**
** The behavior of sqliteVdbeExec() is influenced by the parameters to
** this routine.  If xCallback is NULL, then sqliteVdbeExec() will return
** with SQLITE_CALLBACK whenever there is a row of the result set ready
** to be delivered.  p->azResColumn will point to the row and 
** p->nResColumn gives the number of columns in the row.  If xCallback
** is not NULL, then the xCallback() routine is invoked to process each
** row in the result set.
*/
void sqliteVdbeMakeReady(
  Vdbe *p,                       /* The VDBE */
................................................................................
**
** sqliteVdbeMakeReady() must be called before this routine in order to
** close the program with a final OP_Halt and to set up the callbacks
** and the error message pointer.
**
** Whenever a row or result data is available, this routine will either
** invoke the result callback (if there is one) or return with
** SQLITE_CALLBACK.
**
** If an attempt is made to open a locked database, then this routine
** will either invoke the busy callback (if there is one) or it will
** return SQLITE_BUSY.
**
** If an error occurs, an error message is written to memory obtained
** from sqliteMalloc() and p->zErrMsg is made to point to that memory.
................................................................................
  }
  zStack[p->tos+1] = 0;
  if( p->xCallback==0 ){
    p->azResColumn = &zStack[i];
    p->nResColumn = pOp->p1;
    p->popStack = pOp->p1;
    p->pc = pc + 1;
    return SQLITE_CALLBACK;
  }
  if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; 
  if( p->xCallback(p->pCbArg, pOp->p1, &zStack[i], p->azColName)!=0 ){
    rc = SQLITE_ABORT;
  }
  if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
  p->nCallback++;
................................................................................
    if( p->xCallback(p->pCbArg, pOp->p1, 0, p->azColName)!=0 ){
      rc = SQLITE_ABORT;
    }
    if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
    p->nCallback++;
    if( sqlite_malloc_failed ) goto no_mem;
  }

  break;
}

/* Opcode: Concat P1 P2 P3
**
** Look at the first P1 elements of the stack.  Append them all 
** together with the lowest element first.  Use P3 as a separator.  
................................................................................
  int i = p->tos;
  VERIFY( if( i<0 ) goto not_enough_stack; )
  if( p->xCallback==0 ){
    p->pc = pc+1;
    p->azResColumn = (char**)zStack[i];
    p->nResColumn = pOp->p1;
    p->popStack = 1;
    return SQLITE_CALLBACK;
  }else{
    if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
    if( p->xCallback(p->pCbArg, pOp->p1, (char**)zStack[i], p->azColName)!=0 ){
      rc = SQLITE_ABORT;
    }
    if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
    p->nCallback++;







|







 







>







 







>
>
>
>
>
>







 







>





>
>
>
>





|










>
>
>







 







>
>
>
>
>
>
>
>
>
>







 







|







 







|







 







|







 







|







 







>







 







|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
...
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
...
766
767
768
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
....
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
....
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
....
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
....
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
....
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
....
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
....
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
**
** 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.201 2003/01/29 14:06:09 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The makefile scans this source file and creates the following
** array of string constants which are the names of all VDBE opcodes.
................................................................................
** state of the virtual machine.
**
** The "sqlite_vm" structure pointer that is returned by sqlite_compile()
** is really a pointer to an instance of this structure.
*/
struct Vdbe {
  sqlite *db;         /* The whole database */
  Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
  Btree *pBt;         /* Opaque context structure used by DB backend */
  FILE *trace;        /* Write an execution trace here, if not NULL */
  int nOp;            /* Number of instructions in the program */
  int nOpAlloc;       /* Number of slots allocated for aOp[] */
  Op *aOp;            /* Space to hold the virtual machine's program */
  int nLabel;         /* Number of labels used */
  int nLabelAlloc;    /* Number of slots allocated in aLabel[] */
................................................................................
*/
Vdbe *sqliteVdbeCreate(sqlite *db){
  Vdbe *p;
  p = sqliteMalloc( sizeof(Vdbe) );
  if( p==0 ) return 0;
  p->pBt = db->pBe;
  p->db = db;
  if( db->pVdbe ){
    db->pVdbe->pPrev = p;
  }
  p->pNext = db->pVdbe;
  p->pPrev = 0;
  db->pVdbe = p;
  p->magic = VDBE_MAGIC_INIT;
  return p;
}

/*
** Turn tracing on or off
*/
................................................................................
int sqlite_step(
  sqlite_vm *pVm,              /* The virtual machine to execute */
  int *pN,                     /* OUT: Number of columns in result */
  const char ***pazValue,      /* OUT: Column data */
  const char ***pazColName     /* OUT: Column names and datatypes */
){
  Vdbe *p = (Vdbe*)pVm;
  sqlite *db;
  int rc;

  if( p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_MISUSE;
  }
  db = p->db;
  if( sqliteSafetyOn(db) ){
    return SQLITE_MISUSE;
  }
  if( p->explain ){
    rc = sqliteVdbeList(p);
  }else{
    rc = sqliteVdbeExec(p);
  }
  if( rc==SQLITE_DONE || rc==SQLITE_ROW ){
    *pazColName = (const char**)p->azColName;
    *pN = p->nResColumn;
  }else{
    *pN = 0;
    *pazColName = 0;
  }
  if( rc==SQLITE_ROW ){
    *pazValue = (const char**)p->azResColumn;
  }else{
    *pazValue = 0;
  }
  if( sqliteSafetyOff(db) ){
    return SQLITE_MISUSE;
  }
  return rc;
}

/*
** Reset an Agg structure.  Delete all its contents. 
**
................................................................................
/*
** Delete an entire VDBE.
*/
void sqliteVdbeDelete(Vdbe *p){
  int i;
  if( p==0 ) return;
  Cleanup(p);
  if( p->pPrev ){
    p->pPrev->pNext = p->pNext;
  }else{
    assert( p->db->pVdbe==p );
    p->db->pVdbe = p->pNext;
  }
  if( p->pNext ){
    p->pNext->pPrev = p->pPrev;
  }
  p->pPrev = p->pNext = 0;
  if( p->nOpAlloc==0 ){
    p->aOp = 0;
    p->nOp = 0;
  }
  for(i=0; i<p->nOp; i++){
    if( p->aOp[i].p3type==P3_DYNAMIC ){
      sqliteFree(p->aOp[i].p3);
................................................................................
      p->zStack[4] = p->aOp[i].p3;
    }
    p->zStack[1] = sqliteOpcodeNames[p->aOp[i].opcode];
    if( p->xCallback==0 ){
      p->pc = i+1;
      p->azResColumn = p->zStack;
      p->nResColumn = 5;
      return SQLITE_ROW;
    }
    if( sqliteSafetyOff(db) ){
      p->rc = SQLITE_MISUSE;
      break;
    }
    if( p->xCallback(p->pCbArg, 5, p->zStack, p->azColName) ){
      p->rc = SQLITE_ABORT;
................................................................................
** Prepare a virtual machine for execution.  This involves things such
** as allocating stack space and initializing the program counter.
** After the VDBE has be prepped, it can be executed by one or more
** calls to sqliteVdbeExec().  
**
** The behavior of sqliteVdbeExec() is influenced by the parameters to
** this routine.  If xCallback is NULL, then sqliteVdbeExec() will return
** with SQLITE_ROW whenever there is a row of the result set ready
** to be delivered.  p->azResColumn will point to the row and 
** p->nResColumn gives the number of columns in the row.  If xCallback
** is not NULL, then the xCallback() routine is invoked to process each
** row in the result set.
*/
void sqliteVdbeMakeReady(
  Vdbe *p,                       /* The VDBE */
................................................................................
**
** sqliteVdbeMakeReady() must be called before this routine in order to
** close the program with a final OP_Halt and to set up the callbacks
** and the error message pointer.
**
** Whenever a row or result data is available, this routine will either
** invoke the result callback (if there is one) or return with
** SQLITE_ROW.
**
** If an attempt is made to open a locked database, then this routine
** will either invoke the busy callback (if there is one) or it will
** return SQLITE_BUSY.
**
** If an error occurs, an error message is written to memory obtained
** from sqliteMalloc() and p->zErrMsg is made to point to that memory.
................................................................................
  }
  zStack[p->tos+1] = 0;
  if( p->xCallback==0 ){
    p->azResColumn = &zStack[i];
    p->nResColumn = pOp->p1;
    p->popStack = pOp->p1;
    p->pc = pc + 1;
    return SQLITE_ROW;
  }
  if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; 
  if( p->xCallback(p->pCbArg, pOp->p1, &zStack[i], p->azColName)!=0 ){
    rc = SQLITE_ABORT;
  }
  if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
  p->nCallback++;
................................................................................
    if( p->xCallback(p->pCbArg, pOp->p1, 0, p->azColName)!=0 ){
      rc = SQLITE_ABORT;
    }
    if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
    p->nCallback++;
    if( sqlite_malloc_failed ) goto no_mem;
  }
  p->nResColumn = pOp->p1;
  break;
}

/* Opcode: Concat P1 P2 P3
**
** Look at the first P1 elements of the stack.  Append them all 
** together with the lowest element first.  Use P3 as a separator.  
................................................................................
  int i = p->tos;
  VERIFY( if( i<0 ) goto not_enough_stack; )
  if( p->xCallback==0 ){
    p->pc = pc+1;
    p->azResColumn = (char**)zStack[i];
    p->nResColumn = pOp->p1;
    p->popStack = 1;
    return SQLITE_ROW;
  }else{
    if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
    if( p->xCallback(p->pCbArg, pOp->p1, (char**)zStack[i], p->azColName)!=0 ){
      rc = SQLITE_ABORT;
    }
    if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
    p->nCallback++;

Changes to src/vdbe.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
*************************************************************************
** 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.62 2003/01/28 23:13:13 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
** The following macro converts a relative address in the p2 field
** of a VdbeOp structure into a negative number so that 
** sqliteVdbeAddOpList() knows that the address is relative.  Calling
** the macro again restores the address.
*/
#define ADDR(X)  (-1-(X))

/*
** The sqliteVdbeExec() routine can return any of the normal SQLite return
** codes defined in sqlite.h.  But it can also return the following
** additional values:
*/
#define SQLITE_CALLBACK    100    /* sqliteVdbeExec() hit an OP_Callback */

/*
** The makefile scans the vdbe.c source file and creates the "opcodes.h"
** header file that defines a number for each opcode used by the VDBE.
*/
#include "opcodes.h"

/*







|







 







<
<
<
<
<
<
<







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
58
59
60
61
62
63
64







65
66
67
68
69
70
71
*************************************************************************
** 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.63 2003/01/29 14:06:10 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
** The following macro converts a relative address in the p2 field
** of a VdbeOp structure into a negative number so that 
** sqliteVdbeAddOpList() knows that the address is relative.  Calling
** the macro again restores the address.
*/
#define ADDR(X)  (-1-(X))








/*
** The makefile scans the vdbe.c source file and creates the "opcodes.h"
** header file that defines a number for each opcode used by the VDBE.
*/
#include "opcodes.h"

/*

Added test/capi2.test.

























































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# 2003 January 29
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi2.test,v 1.1 2003/01/29 14:06:10 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Check basic functionality
#
do_test capi2-1.1 {
  db close
  set ::DB [sqlite db test.db]
  execsql {CREATE TABLE t1(a,b,c)}
  set ::VM [sqlite_compile $::DB {SELECT name, rowid FROM sqlite_master} tail]
  set tail
} {}
do_test capi2-1.2 {
  sqlite_step $::VM ::N ::VALUES ::COLNAMES
} {SQLITE_ROW}
do_test capi2-1.3 {
  set ::N
} {2}
do_test capi2-1.4 {
  set ::VALUES
} {t1 1}
do_test capi2-1.5 {
  set ::COLNAMES
} {name rowid text INTEGER}
do_test capi2-1.6 {
  set ::N x
  set ::VALUES y
  set ::COLNAMES z
  sqlite_step $::VM ::N ::VALUES ::COLNAMES
} {SQLITE_DONE}
do_test capi2-1.7 {
  list $::N $::VALUES $::COLNAMES
} {2 {} {name rowid text INTEGER}}
do_test capi2-1.8 {
  set ::N x
  set ::VALUES y
  set ::COLNAMES z
  sqlite_step $::VM ::N ::VALUES ::COLNAMES
} {SQLITE_MISUSE}
do_test capi2-1.9 {
  list $::N $::VALUES $::COLNAMES
} {x y z}
do_test capi2-1.10 {
  sqlite_finalize $::VM
} {}

# Check to make sure that the "tail" of a multi-statement SQL script
# is returned by sqlite_compile.
#
do_test capi2-2.1 {
  set ::SQL {
    SELECT name, rowid FROM sqlite_master;
    SELECT name, rowid FROM sqlite_temp_master;
    -- A comment at the end
  }
  set ::VM [sqlite_compile $::DB $::SQL ::SQL]
  set ::SQL
} {
    SELECT name, rowid FROM sqlite_temp_master;
    -- A comment at the end
  }
do_test capi2-2.2 {
  set r [sqlite_step $::VM n val colname]
  lappend r $n $val $colname
} {SQLITE_ROW 2 {t1 1} {name rowid text INTEGER}}
do_test capi2-2.3 {
  set r [sqlite_step $::VM n val colname]
  lappend r $n $val $colname
} {SQLITE_DONE 2 {} {name rowid text INTEGER}}
do_test capi2-2.4 {
  sqlite_finalize $::VM
} {}
do_test capi2-2.5 {
  set ::VM [sqlite_compile $::DB $::SQL ::SQL]
  set ::SQL
} {
    -- A comment at the end
  }
do_test capi2-2.6 {
  set r [sqlite_step $::VM n val colname]
  lappend r $n $val $colname
} {SQLITE_DONE 2 {} {name rowid text INTEGER}}
do_test capi2-2.7 {
  sqlite_finalize $::VM
} {}
do_test capi2-2.8 {
  set ::VM [sqlite_compile $::DB $::SQL ::SQL]
  list $::SQL $::VM
} {{} {}}


finish_test