/ Check-in [2dbc4593]
Login

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

Overview
Comment:Eliminate obsolete code associated with the older callback functionality. (CVS 1243)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2dbc4593ca5c1cf75039c8b4471b1e47faa849f0
User & Date: drh 2004-02-14 23:59:57
Context
2004-02-16
03:44
Remove the NullCallback opcode. Handle the empty_result_set pragma inside the sqlite_exec() function. (CVS 1244) check-in: f7213485 user: drh tags: trunk
2004-02-14
23:59
Eliminate obsolete code associated with the older callback functionality. (CVS 1243) check-in: 2dbc4593 user: drh tags: trunk
23:05
Eliminate the use of callbacks during schema initialization. (CVS 1242) check-in: af5c2be4 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
..
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.169 2004/02/14 23:05:53 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
................................................................................
    if( !db->aDb[i].inTrans ){
      DbClearProperty(db, i, DB_Cookie);
    }
  }
  pParse->nVar = 0;
}

/*
** This is a fake callback procedure used when sqlite_exec() is
** invoked with a NULL callback pointer.  If we pass a NULL callback
** pointer into sqliteVdbeExec() it will return at every OP_Callback,
** which we do not want it to do.  So we substitute a pointer to this
** procedure in place of the NULL.
*/
static int fakeCallback(void *NotUsed, int n, char **az1, char **az2){
  return 0;
}

/*
** This routine is called after a single SQL statement has been
** parsed and we want to execute the VDBE code to implement 
** that statement.  Prior action routines should have already
** constructed VDBE code to do the work of the SQL statement.
** This routine just has to execute the VDBE code.
**
** Note that if an error occurred, it might be the case that
** no VDBE code was generated.
*/
void sqliteExec(Parse *pParse){
  int rc = SQLITE_OK;
  sqlite *db = pParse->db;
  Vdbe *v = pParse->pVdbe;
  int (*xCallback)(void*,int,char**,char**);

  if( sqlite_malloc_failed ) return;
  xCallback = pParse->xCallback;
  if( xCallback==0 ){
    if( pParse->useCallback ){
      xCallback = fakeCallback;
    }else if( v==0 ){
      v = sqliteGetVdbe(pParse);
      sqliteVdbeAddOp(v, OP_Halt, 0, 0);
    }
  }

  if( v && pParse->nErr==0 ){
    FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
    sqliteVdbeTrace(v, trace);
    sqliteVdbeMakeReady(v, pParse->nVar, xCallback, pParse->pArg,
                        pParse->explain);
    if( pParse->useCallback ){
      if( pParse->explain ){
        rc = sqliteVdbeList(v);
        db->next_cookie = db->aDb[0].schema_cookie;
      }else{
        sqliteVdbeExec(v);
      }
      rc = sqliteVdbeFinalize(v, &pParse->zErrMsg);
      if( rc ) pParse->nErr++;
      pParse->pVdbe = 0;
      pParse->rc = rc;
      if( rc ) pParse->nErr++;
    }else{
      pParse->rc = pParse->nErr ? SQLITE_ERROR : SQLITE_DONE;
    }
    pParse->colNamesSet = 0;
  }else if( pParse->useCallback==0 && pParse->rc==SQLITE_OK ){
    pParse->rc = SQLITE_ERROR;
  }
  pParse->nTab = 0;
  pParse->nMem = 0;
  pParse->nSet = 0;
  pParse->nAgg = 0;
  pParse->nVar = 0;







|







 







<
<
<
<
<
<
<
<
<
<
<











<


<

<
<
<
<
<
<
|
|
|
<
>



|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<

|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
..
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
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.170 2004/02/14 23:59:57 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
................................................................................
    if( !db->aDb[i].inTrans ){
      DbClearProperty(db, i, DB_Cookie);
    }
  }
  pParse->nVar = 0;
}












/*
** This routine is called after a single SQL statement has been
** parsed and we want to execute the VDBE code to implement 
** that statement.  Prior action routines should have already
** constructed VDBE code to do the work of the SQL statement.
** This routine just has to execute the VDBE code.
**
** Note that if an error occurred, it might be the case that
** no VDBE code was generated.
*/
void sqliteExec(Parse *pParse){

  sqlite *db = pParse->db;
  Vdbe *v = pParse->pVdbe;








  if( v==0 && (v = sqliteGetVdbe(pParse))!=0 ){
    sqliteVdbeAddOp(v, OP_Halt, 0, 0);
  }

  if( sqlite_malloc_failed ) return;
  if( v && pParse->nErr==0 ){
    FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
    sqliteVdbeTrace(v, trace);
    sqliteVdbeMakeReady(v, pParse->nVar, pParse->explain);














    pParse->rc = pParse->nErr ? SQLITE_ERROR : SQLITE_DONE;

    pParse->colNamesSet = 0;
  }else if( pParse->rc==SQLITE_OK ){
    pParse->rc = SQLITE_ERROR;
  }
  pParse->nTab = 0;
  pParse->nMem = 0;
  pParse->nSet = 0;
  pParse->nAgg = 0;
  pParse->nVar = 0;

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
...
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
**
*************************************************************************
** 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.154 2004/02/14 23:05:53 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................
      return SQLITE_ERROR;
    }
  }
  assert( (db->flags & SQLITE_Initialized)!=0 || db->init.busy );
  if( db->pVdbe==0 ){ db->nChange = 0; }
  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sParse.useCallback = 0;
  if( db->xTrace ) db->xTrace(db->pTraceArg, zSql);
  sqliteRunParser(&sParse, zSql, pzErrMsg);
  if( sqlite_malloc_failed ){
    sqliteSetString(pzErrMsg, "out of memory", (char*)0);
    sParse.rc = SQLITE_NOMEM;
    sqliteRollbackAll(db);
    sqliteResetInternalSchema(db, 0);
................................................................................
** 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, -1, 0, 0, 0);
  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
...
696
697
698
699
700
701
702

703
704
705
706
707
708
709
...
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
**
*************************************************************************
** 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.155 2004/02/14 23:59:57 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................
      return SQLITE_ERROR;
    }
  }
  assert( (db->flags & SQLITE_Initialized)!=0 || db->init.busy );
  if( db->pVdbe==0 ){ db->nChange = 0; }
  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;

  if( db->xTrace ) db->xTrace(db->pTraceArg, zSql);
  sqliteRunParser(&sParse, zSql, pzErrMsg);
  if( sqlite_malloc_failed ){
    sqliteSetString(pzErrMsg, "out of memory", (char*)0);
    sParse.rc = SQLITE_NOMEM;
    sqliteRollbackAll(db);
    sqliteResetInternalSchema(db, 0);
................................................................................
** 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, -1, 0);
  sqliteStrRealloc(pzErrMsg);
  return rc;
}

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

Changes to src/parse.y.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
**
*************************************************************************
** 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.109 2004/02/12 18:46:39 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  if( pParse->zErrMsg==0 ){
................................................................................
// These are extra tokens used by the lexer but never seen by the
// parser.  We put them in a rule so that the parser generator will
// add them to the parse.h output file.
//
%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
          COLUMN AGG_FUNCTION.

// Input is zero or more commands.
input ::= cmdlist.

// A list of commands is zero or more commands
//
cmdlist ::= ecmd.
cmdlist ::= cmdlist ecmd.
ecmd ::= explain cmdx SEMI.
ecmd ::= SEMI.
cmdx ::= cmd.           { sqliteExec(pParse); }
explain ::= EXPLAIN.    { sqliteBeginParse(pParse, 1); }
explain ::= .           { sqliteBeginParse(pParse, 0); }

///////////////////// Begin and end transactions. ////////////////////////////







|







 







|

<
<
<
|
|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
61
62
63
64
65
66
67
68
69



70
71
72
73
74
75
76
77
78
**
*************************************************************************
** 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.110 2004/02/14 23:59:57 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  if( pParse->zErrMsg==0 ){
................................................................................
// These are extra tokens used by the lexer but never seen by the
// parser.  We put them in a rule so that the parser generator will
// add them to the parse.h output file.
//
%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
          COLUMN AGG_FUNCTION.

// Input is a single SQL command
input ::= cmdlist.



cmdlist ::= cmdlist ecmd.
cmdlist ::= ecmd.
ecmd ::= explain cmdx SEMI.
ecmd ::= SEMI.
cmdx ::= cmd.           { sqliteExec(pParse); }
explain ::= EXPLAIN.    { sqliteBeginParse(pParse, 1); }
explain ::= .           { sqliteBeginParse(pParse, 0); }

///////////////////// Begin and end transactions. ////////////////////////////

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
....
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
....
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
**    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.154 2004/02/14 16:31:04 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
static void generateColumnTypes(
  Parse *pParse,      /* Parser context */
  SrcList *pTabList,  /* List of tables */
  ExprList *pEList    /* Expressions defining the result set */
){
  Vdbe *v = pParse->pVdbe;
  int i, j;
  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;
      int iCol = p->iColumn;
................................................................................
    sqliteErrorMsg(pParse, "SELECTs to the left and right of %s"
      " do not have the same number of result columns", selectOpName(p->op));
    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;
}

/*
** Scan through the expression pExpr.  Replace every reference to
................................................................................
  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);
  }

  /* If this was a subquery, we have now converted the subquery into a
  ** temporary table.  So delete the subquery structure from the parent
  ** to prevent this subquery from being evaluated again and to force the
  ** the use of the temporary table.







|







 







<
<
<







 







|
<
<







 







|
<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
644
645
646
647
648
649
650



651
652
653
654
655
656
657
....
1495
1496
1497
1498
1499
1500
1501
1502


1503
1504
1505
1506
1507
1508
1509
....
2393
2394
2395
2396
2397
2398
2399
2400


2401
2402
2403
2404
2405
2406
2407
**    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.155 2004/02/14 23:59:58 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
static void generateColumnTypes(
  Parse *pParse,      /* Parser context */
  SrcList *pTabList,  /* List of tables */
  ExprList *pEList    /* Expressions defining the result set */
){
  Vdbe *v = pParse->pVdbe;
  int i, j;



  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;
      int iCol = p->iColumn;
................................................................................
    sqliteErrorMsg(pParse, "SELECTs to the left and right of %s"
      " do not have the same number of result columns", selectOpName(p->op));
    return 1;
  }

  /* Issue a null callback if that is what the user wants.
  */
  if( eDest==SRT_Callback ){


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

/*
** Scan through the expression pExpr.  Replace every reference to
................................................................................
  if( pOrderBy ){
    generateSortTail(p, v, pEList->nExpr, eDest, iParm);
  }


  /* Issue a null callback if that is what the user wants.
  */
  if( eDest==SRT_Callback ){


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

  /* If this was a subquery, we have now converted the subquery into a
  ** temporary table.  So delete the subquery structure from the parent
  ** to prevent this subquery from being evaluated again and to force the
  ** the use of the temporary table.

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
**    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.212 2004/02/14 23:05:53 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
................................................................................
** An SQL parser context.  A copy of this structure is passed through
** the parser and down into all the parser action routine in order to
** carry around information that is global to the entire parse.
*/
struct Parse {
  sqlite *db;          /* The main database structure */
  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 nameClash;        /* A permanent table name clashes with temp table name */
  u8 useAgg;           /* If true, extract field values from the aggregator
                       ** while generating expressions.  Normally false */
  u8 useCallback;      /* True if callbacks should be used to report results */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  int nAgg;            /* Number of aggregate expressions */
  int nVar;            /* Number of '?' variables seen in the SQL so far */
  AggExpr *aAgg;       /* An array of aggregate expressions */







|







 







<
<












<







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
868
869
870
871
872
873
874


875
876
877
878
879
880
881
882
883
884
885
886

887
888
889
890
891
892
893
**    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.213 2004/02/14 23:59:58 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
................................................................................
** An SQL parser context.  A copy of this structure is passed through
** the parser and down into all the parser action routine in order to
** carry around information that is global to the entire parse.
*/
struct Parse {
  sqlite *db;          /* The main database structure */
  int rc;              /* Return code from execution */


  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 nameClash;        /* A permanent table name clashes with temp table name */
  u8 useAgg;           /* If true, extract field values from the aggregator
                       ** while generating expressions.  Normally false */

  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  int nAgg;            /* Number of aggregate expressions */
  int nVar;            /* Number of '?' variables seen in the SQL so far */
  AggExpr *aAgg;       /* An array of aggregate expressions */

Changes to src/tokenize.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
*************************************************************************
** 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.67 2004/01/08 02:17:33 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
      *pzErrMsg = pParse->zErrMsg;
    }else{
      sqliteFree(pParse->zErrMsg);
    }
    pParse->zErrMsg = 0;
    if( !nErr ) nErr++;
  }
  if( pParse->pVdbe && (pParse->useCallback || pParse->nErr>0) ){
    sqliteVdbeDelete(pParse->pVdbe);
    pParse->pVdbe = 0;
  }
  if( pParse->pNewTable ){
    sqliteDeleteTable(pParse->db, pParse->pNewTable);
    pParse->pNewTable = 0;
  }







|







 







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
*************************************************************************
** 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.68 2004/02/14 23:59:58 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
      *pzErrMsg = pParse->zErrMsg;
    }else{
      sqliteFree(pParse->zErrMsg);
    }
    pParse->zErrMsg = 0;
    if( !nErr ) nErr++;
  }
  if( pParse->pVdbe && pParse->nErr>0 ){
    sqliteVdbeDelete(pParse->pVdbe);
    pParse->pVdbe = 0;
  }
  if( pParse->pNewTable ){
    sqliteDeleteTable(pParse->db, pParse->pNewTable);
    pParse->pNewTable = 0;
  }

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
...
904
905
906
907
908
909
910

911
912
913
914
915
916
917
918
919
920
921
922
923
924

925
926
927
928
929
930
931
932
933
934
935
936
....
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
**
** 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.263 2004/02/14 17:35:07 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
    }else{
      Stringify(pCol);
      azArgv[i] = pCol->z;
    }
  }
  azArgv[i] = 0;
  p->nCallback++;
  if( p->xCallback==0 ){
    p->azResColumn = azArgv;
    p->nResColumn = pOp->p1;
    p->popStack = pOp->p1;
    p->pc = pc + 1;
    p->pTos = pTos;
    return SQLITE_ROW;
  }
  if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; 
  if( p->xCallback(p->pCbArg, pOp->p1, azArgv, p->azColName)!=0 ){
    rc = SQLITE_ABORT;
  }
  if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
  popStack(&pTos, pOp->p1);
  assert( pTos>=&p->aStack[-1] );
  if( sqlite_malloc_failed ) goto no_mem;
  break;
}

/* Opcode: NullCallback P1 * *
**
** Invoke the callback function once with the 2nd argument (the
** number of columns) equal to P1 and with the 4th argument (the
** names of the columns) set according to prior OP_ColumnName
................................................................................
** The callback is only invoked if there have been no prior calls
** to OP_Callback or OP_SortCallback.
**
** This opcode is used to report the number and names of columns
** in cases where the result set is empty.
*/
case OP_NullCallback: {

  if( p->nCallback==0 && (db->flags & SQLITE_NullCallback)!=0 ){
    if( p->xCallback!=0 ){
      if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; 
      if( p->xCallback(p->pCbArg, pOp->p1, 0, p->azColName)!=0 ){
        rc = SQLITE_ABORT;
      }
      if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
      if( sqlite_malloc_failed ) goto no_mem;
    }else{
      p->azResColumn = 0;
      p->nResColumn = pOp->p1;
      p->popStack = 0;
      p->pc = pc + 1;
      p->pTos = pTos;

      return SQLITE_ROW;
    }
    p->nCallback++;
  }
  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.  
................................................................................
** instruction.  Pop this record from the stack and invoke the
** callback on it.
*/
case OP_SortCallback: {
  assert( pTos>=p->aStack );
  assert( pTos->flags & MEM_Str );
  p->nCallback++;
  if( p->xCallback==0 ){
    p->pc = pc+1;
    p->azResColumn = (char**)pTos->z;
    p->nResColumn = pOp->p1;
    p->popStack = 1;
    p->pTos = pTos;
    return SQLITE_ROW;
  }else{
    if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
    if( p->xCallback(p->pCbArg, pOp->p1, (char**)pTos->z, p->azColName)!=0){
      rc = SQLITE_ABORT;
    }
    if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
  }
  Release(pTos);
  pTos--;
  if( sqlite_malloc_failed ) goto no_mem;
  break;
}

/* Opcode: SortReset * * *
**
** Remove any elements that remain on the sorter.
*/
case OP_SortReset: {







|







 







<
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<







 







>

<
<
<
<
<
<
<
<
|
<
|
|
|
>
|
|
<
<
<







 







<
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
868
869
870
871
872
873
874

875
876
877
878
879
880










881
882
883
884
885
886
887
...
893
894
895
896
897
898
899
900
901








902

903
904
905
906
907
908



909
910
911
912
913
914
915
....
4070
4071
4072
4073
4074
4075
4076

4077
4078
4079
4080
4081
4082











4083
4084
4085
4086
4087
4088
4089
**
** 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.264 2004/02/14 23:59:58 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
    }else{
      Stringify(pCol);
      azArgv[i] = pCol->z;
    }
  }
  azArgv[i] = 0;
  p->nCallback++;

  p->azResColumn = azArgv;
  p->nResColumn = pOp->p1;
  p->popStack = pOp->p1;
  p->pc = pc + 1;
  p->pTos = pTos;
  return SQLITE_ROW;










}

/* Opcode: NullCallback P1 * *
**
** Invoke the callback function once with the 2nd argument (the
** number of columns) equal to P1 and with the 4th argument (the
** names of the columns) set according to prior OP_ColumnName
................................................................................
** The callback is only invoked if there have been no prior calls
** to OP_Callback or OP_SortCallback.
**
** This opcode is used to report the number and names of columns
** in cases where the result set is empty.
*/
case OP_NullCallback: {
  p->nResColumn = pOp->p1;
  if( p->nCallback==0 && (db->flags & SQLITE_NullCallback)!=0 ){








    p->azResColumn = 0;

    p->popStack = 0;
    p->pc = pc + 1;
    p->pTos = pTos;
    p->nCallback++;
    return SQLITE_ROW;
  }



  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.  
................................................................................
** instruction.  Pop this record from the stack and invoke the
** callback on it.
*/
case OP_SortCallback: {
  assert( pTos>=p->aStack );
  assert( pTos->flags & MEM_Str );
  p->nCallback++;

  p->pc = pc+1;
  p->azResColumn = (char**)pTos->z;
  p->nResColumn = pOp->p1;
  p->popStack = 1;
  p->pTos = pTos;
  return SQLITE_ROW;











}

/* Opcode: SortReset * * *
**
** Remove any elements that remain on the sorter.
*/
case OP_SortReset: {

Changes to src/vdbe.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
80
81
82
83
84
85
86
87
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.68 2003/09/06 22:18:08 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
void sqliteVdbeChangeP2(Vdbe*, int addr, int P2);
void sqliteVdbeChangeP3(Vdbe*, int addr, const char *zP1, int N);
void sqliteVdbeDequoteP3(Vdbe*, int addr);
int sqliteVdbeFindOp(Vdbe*, int, int);
VdbeOp *sqliteVdbeGetOp(Vdbe*, int);
int sqliteVdbeMakeLabel(Vdbe*);
void sqliteVdbeDelete(Vdbe*);
void sqliteVdbeMakeReady(Vdbe*,int,sqlite_callback,void*,int);
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







|







 







|











11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
80
81
82
83
84
85
86
87
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.69 2004/02/14 23:59:58 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
void sqliteVdbeChangeP2(Vdbe*, int addr, int P2);
void sqliteVdbeChangeP3(Vdbe*, int addr, const char *zP1, int N);
void sqliteVdbeDequoteP3(Vdbe*, int addr);
int sqliteVdbeFindOp(Vdbe*, int, int);
VdbeOp *sqliteVdbeGetOp(Vdbe*, int);
int sqliteVdbeMakeLabel(Vdbe*);
void sqliteVdbeDelete(Vdbe*);
void sqliteVdbeMakeReady(Vdbe*,int,int);
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

Changes to src/vdbeInt.h.

255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
  unsigned uniqueCnt;     /* Used by OP_MakeRecord when P2!=0 */
  int errorAction;        /* Recovery action to do in case of an error */
  int undoTransOnError;   /* If error, either ROLLBACK or COMMIT */
  int inTempTrans;        /* True if temp database is transactioned */
  int returnStack[100];   /* Return address stack for OP_Gosub & OP_Return */
  int returnDepth;        /* Next unused element in returnStack[] */
  int nResColumn;         /* Number of columns in one row of the result set */
  char **azResColumn;                        /* Values for one row of result */ 
  int (*xCallback)(void*,int,char**,char**); /* Callback for SELECT results */
  void *pCbArg;                              /* First argument to xCallback() */
  int popStack;           /* Pop the stack this much on entry to VdbeExec() */
  char *zErrMsg;          /* Error message written here */
  u8 explain;             /* True if EXPLAIN present on SQL command */
};

/*
** The following are allowed values for Vdbe.magic







|
<
<







255
256
257
258
259
260
261
262


263
264
265
266
267
268
269
  unsigned uniqueCnt;     /* Used by OP_MakeRecord when P2!=0 */
  int errorAction;        /* Recovery action to do in case of an error */
  int undoTransOnError;   /* If error, either ROLLBACK or COMMIT */
  int inTempTrans;        /* True if temp database is transactioned */
  int returnStack[100];   /* Return address stack for OP_Gosub & OP_Return */
  int returnDepth;        /* Next unused element in returnStack[] */
  int nResColumn;         /* Number of columns in one row of the result set */
  char **azResColumn;     /* Values for one row of result */ 


  int popStack;           /* Pop the stack this much on entry to VdbeExec() */
  char *zErrMsg;          /* Error message written here */
  u8 explain;             /* True if EXPLAIN present on SQL command */
};

/*
** The following are allowed values for Vdbe.magic

Changes to src/vdbeaux.c.

496
497
498
499
500
501
502

503
504
505
506
507
508
509
510
511
512
513


514
515

516
517
518
519
520
521
522

523
524
525

526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553

554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
...
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
** This feature is used to implement "EXPLAIN".
*/
int sqliteVdbeList(
  Vdbe *p                   /* The VDBE */
){
  sqlite *db = p->db;
  int i;

  static char *azColumnNames[] = {
     "addr", "opcode", "p1",  "p2",  "p3", 
     "int",  "text",   "int", "int", "text",
     0
  };

  assert( p->popStack==0 );
  assert( p->explain );
  p->azColName = azColumnNames;
  p->azResColumn = p->zArgv;
  for(i=0; i<5; i++) p->zArgv[i] = p->aStack[i].zShort;


  p->rc = SQLITE_OK;
  for(i=p->pc; p->rc==SQLITE_OK && i<p->nOp; i++){

    if( db->flags & SQLITE_Interrupt ){
      db->flags &= ~SQLITE_Interrupt;
      if( db->magic!=SQLITE_MAGIC_BUSY ){
        p->rc = SQLITE_MISUSE;
      }else{
        p->rc = SQLITE_INTERRUPT;
      }

      sqliteSetString(&p->zErrMsg, sqlite_error_string(p->rc), (char*)0);
      break;
    }

    sprintf(p->zArgv[0],"%d",i);
    sprintf(p->zArgv[2],"%d", p->aOp[i].p1);
    sprintf(p->zArgv[3],"%d", p->aOp[i].p2);
    if( p->aOp[i].p3type==P3_POINTER ){
      sprintf(p->aStack[4].zShort, "ptr(%#x)", (int)p->aOp[i].p3);
      p->zArgv[4] = p->aStack[4].zShort;
    }else{
      p->zArgv[4] = p->aOp[i].p3;
    }
    p->zArgv[1] = sqliteOpcodeNames[p->aOp[i].opcode];
    if( p->xCallback==0 ){
      p->pc = i+1;
      p->azResColumn = p->zArgv;
      p->nResColumn = 5;
      return SQLITE_ROW;
    }
    if( sqliteSafetyOff(db) ){
      p->rc = SQLITE_MISUSE;
      break;
    }
    if( p->xCallback(p->pCbArg, 5, p->zArgv, p->azColName) ){
      p->rc = SQLITE_ABORT;
    }
    if( sqliteSafetyOn(db) ){
      p->rc = SQLITE_MISUSE;
    }
  }
  return p->rc==SQLITE_OK ? SQLITE_DONE : SQLITE_ERROR;

}

/*
** 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 */
  int nVar,                      /* Number of '?' see in the SQL statement */
  sqlite_callback xCallback,     /* Result callback */
  void *pCallbackArg,            /* 1st argument to xCallback() */
  int isExplain                  /* True if the EXPLAIN keywords is present */
){
  int n;

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

................................................................................
  p->pTos = &p->aStack[-1];
  p->pc = 0;
  p->rc = SQLITE_OK;
  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
  {
    int i;
    for(i=0; i<p->nOp; i++){







>











>
>
|
<
>
|
|
|
|
|
|
|
>
|
<
<
>










<
|
|
|
<
<
<
<
<
<
<
|
<
<
|
|
<
<
>







<
<
<
<
<
<
<
<




<
<







 







<
<







496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517

518
519
520
521
522
523
524
525
526
527


528
529
530
531
532
533
534
535
536
537
538

539
540
541







542


543
544


545
546
547
548
549
550
551
552








553
554
555
556


557
558
559
560
561
562
563
...
599
600
601
602
603
604
605


606
607
608
609
610
611
612
** This feature is used to implement "EXPLAIN".
*/
int sqliteVdbeList(
  Vdbe *p                   /* The VDBE */
){
  sqlite *db = p->db;
  int i;
  int rc = SQLITE_OK;
  static char *azColumnNames[] = {
     "addr", "opcode", "p1",  "p2",  "p3", 
     "int",  "text",   "int", "int", "text",
     0
  };

  assert( p->popStack==0 );
  assert( p->explain );
  p->azColName = azColumnNames;
  p->azResColumn = p->zArgv;
  for(i=0; i<5; i++) p->zArgv[i] = p->aStack[i].zShort;
  i = p->pc;
  if( i>=p->nOp ){
    p->rc = SQLITE_OK;

    rc = SQLITE_DONE;
  }else if( db->flags & SQLITE_Interrupt ){
    db->flags &= ~SQLITE_Interrupt;
    if( db->magic!=SQLITE_MAGIC_BUSY ){
      p->rc = SQLITE_MISUSE;
    }else{
      p->rc = SQLITE_INTERRUPT;
    }
    rc = SQLITE_ERROR;
    sqliteSetString(&p->zErrMsg, sqlite_error_string(p->rc), (char*)0);


  }else{
    sprintf(p->zArgv[0],"%d",i);
    sprintf(p->zArgv[2],"%d", p->aOp[i].p1);
    sprintf(p->zArgv[3],"%d", p->aOp[i].p2);
    if( p->aOp[i].p3type==P3_POINTER ){
      sprintf(p->aStack[4].zShort, "ptr(%#x)", (int)p->aOp[i].p3);
      p->zArgv[4] = p->aStack[4].zShort;
    }else{
      p->zArgv[4] = p->aOp[i].p3;
    }
    p->zArgv[1] = sqliteOpcodeNames[p->aOp[i].opcode];

    p->pc = i+1;
    p->azResColumn = p->zArgv;
    p->nResColumn = 5;







    p->rc = SQLITE_OK;


    rc = SQLITE_ROW;
  }


  return rc;
}

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








*/
void sqliteVdbeMakeReady(
  Vdbe *p,                       /* The VDBE */
  int nVar,                      /* Number of '?' see in the SQL statement */


  int isExplain                  /* True if the EXPLAIN keywords is present */
){
  int n;

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

................................................................................
  p->pTos = &p->aStack[-1];
  p->pc = 0;
  p->rc = SQLITE_OK;
  p->uniqueCnt = 0;
  p->returnDepth = 0;
  p->errorAction = OE_Abort;
  p->undoTransOnError = 0;


  p->popStack =  0;
  p->explain |= isExplain;
  p->magic = VDBE_MAGIC_RUN;
#ifdef VDBE_PROFILE
  {
    int i;
    for(i=0; i<p->nOp; i++){