/ Check-in [6db3f122]
Login

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

Overview
Comment:Fix more problems with deferred execution of CREATE. Still need to do DROP. There is now a memory leak. (CVS 1865)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:6db3f122aad25b5226670ce682b7263d55c0d301
User & Date: drh 2004-07-24 14:35:58
Context
2004-07-24
17:38
Prepared statements now work with CREATE and DROP. All tests pass. No memory leaks. (CVS 1866) check-in: ebdb661e user: drh tags: trunk
14:35
Fix more problems with deferred execution of CREATE. Still need to do DROP. There is now a memory leak. (CVS 1865) check-in: 6db3f122 user: drh tags: trunk
03:30
Progress towards getting prepared statements and CREATE and DROP to play nicely together. Work is incomplete. Some tests are known to fail. (CVS 1864) check-in: 49b99149 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
..
77
78
79
80
81
82
83




84
85
86
87
88
89
90
....
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
....
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.241 2004/07/24 03:30:48 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( (mask & pParse->cookieMask)==0 ) continue;
        sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
        sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
      }
      sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto);
    }
  }





  /* Get the VDBE program ready for execution
  */
  if( v && pParse->nErr==0 ){
    FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
    sqlite3VdbeTrace(v, trace);
    sqlite3VdbeMakeReady(v, pParse->nVar, pParse->explain);
................................................................................
      }
    }
  }
  return SQLITE_AFF_NUMERIC;
}

/*
** Come up with a new random value for the schema cookie.  Make sure
** the new value is different from the old.
**
** The schema cookie is used to determine when the schema for the
** database changes.  After each schema change, the cookie value
** changes.  When a process first reads the schema it records the
** cookie.  Thereafter, whenever it goes to access the database,
** it checks the cookie to make sure the schema has not changed
** since it was last read.
................................................................................
** This plan is not completely bullet-proof.  It is possible for
** the schema to change multiple times and for the cookie to be
** set back to prior value.  But schema changes are infrequent
** and the probability of hitting the same cookie value is only
** 1 chance in 2^32.  So we're safe enough.
*/
void sqlite3ChangeCookie(sqlite *db, Vdbe *v, int iDb){
  unsigned char r;
  int *pSchemaCookie = &(db->aDb[iDb].schema_cookie);

  sqlite3Randomness(1, &r);
  *pSchemaCookie = *pSchemaCookie + r + 1;
  db->flags |= SQLITE_InternChanges;
  sqlite3VdbeAddOp(v, OP_Integer, *pSchemaCookie, 0);
  sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0);
}

/*
** Measure the number of characters needed to output the given
** identifier.  The number returned includes any quotes used
** but does not include the null terminator.







|







 







>
>
>
>







 







|
<







 







<
<
<
<
<
<
|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
..
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
....
1138
1139
1140
1141
1142
1143
1144
1145

1146
1147
1148
1149
1150
1151
1152
....
1154
1155
1156
1157
1158
1159
1160






1161
1162
1163
1164
1165
1166
1167
1168
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.242 2004/07/24 14:35:58 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( (mask & pParse->cookieMask)==0 ) continue;
        sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
        sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
      }
      sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto);
    }
  }

#ifndef NDEBUG
  sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail - pParse->zSql);
#endif

  /* Get the VDBE program ready for execution
  */
  if( v && pParse->nErr==0 ){
    FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
    sqlite3VdbeTrace(v, trace);
    sqlite3VdbeMakeReady(v, pParse->nVar, pParse->explain);
................................................................................
      }
    }
  }
  return SQLITE_AFF_NUMERIC;
}

/*
** Generate code that will increment the schema cookie.

**
** The schema cookie is used to determine when the schema for the
** database changes.  After each schema change, the cookie value
** changes.  When a process first reads the schema it records the
** cookie.  Thereafter, whenever it goes to access the database,
** it checks the cookie to make sure the schema has not changed
** since it was last read.
................................................................................
** This plan is not completely bullet-proof.  It is possible for
** the schema to change multiple times and for the cookie to be
** set back to prior value.  But schema changes are infrequent
** and the probability of hitting the same cookie value is only
** 1 chance in 2^32.  So we're safe enough.
*/
void sqlite3ChangeCookie(sqlite *db, Vdbe *v, int iDb){






  sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].schema_cookie+1, 0);
  sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0);
}

/*
** Measure the number of characters needed to output the given
** identifier.  The number returned includes any quotes used
** but does not include the null terminator.

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
**
*************************************************************************
** 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.247 2004/07/24 03:30:48 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The following constant value is used by the SQLITE_BIGENDIAN and
................................................................................
    rc = SQLITE_NOMEM;
    sqlite3RollbackAll(db);
    sqlite3ResetInternalSchema(db, 0);
    db->flags &= ~SQLITE_InTrans;
    goto prepare_out;
  }
  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
  if( sParse.checkSchema && !schemaIsValid(db) ){
    sParse.rc = SQLITE_SCHEMA;
  }
  if( sParse.rc==SQLITE_SCHEMA ){
    sqlite3ResetInternalSchema(db, 0);
  }
  if( pzTail ) *pzTail = sParse.zTail;
  rc = sParse.rc;







|







 







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
**
*************************************************************************
** 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.248 2004/07/24 14:35:58 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The following constant value is used by the SQLITE_BIGENDIAN and
................................................................................
    rc = SQLITE_NOMEM;
    sqlite3RollbackAll(db);
    sqlite3ResetInternalSchema(db, 0);
    db->flags &= ~SQLITE_InTrans;
    goto prepare_out;
  }
  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
  if( sParse.rc!=SQLITE_OK && sParse.checkSchema && !schemaIsValid(db) ){
    sParse.rc = SQLITE_SCHEMA;
  }
  if( sParse.rc==SQLITE_SCHEMA ){
    sqlite3ResetInternalSchema(db, 0);
  }
  if( pzTail ) *pzTail = sParse.zTail;
  rc = sParse.rc;

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
979
980
981
982
983
984
985

986
987
988
989
990
991
992
**    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.309 2004/07/24 03:30:48 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

#include "config.h"
#include "sqlite3.h"
#include "hash.h"
................................................................................
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 sNameToken;    /* Token with unqualified schema object name */
  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







|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
**    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.310 2004/07/24 14:35:58 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

#include "config.h"
#include "sqlite3.h"
#include "hash.h"
................................................................................
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 sNameToken;    /* Token with unqualified schema object name */
  Token sLastToken;    /* The last token parsed */
  const char *zSql;    /* All SQL text */
  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

Changes to src/tokenize.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
*************************************************************************
** 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.79 2004/07/24 03:30:48 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
  pParse->rc = SQLITE_OK;
  i = 0;
  pEngine = sqlite3ParserAlloc((void*(*)(int))malloc);
  if( pEngine==0 ){
    sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
    return 1;
  }
#ifndef NDEBUG
  if( sqlite3OsFileExists("vdbe_sqltrace") ){
    printf("SQL To Compiler: [%s]\n", zSql);
  }
#endif
  pParse->sLastToken.dyn = 0;
  pParse->zTail = zSql;
  while( sqlite3_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;
    switch( tokenType ){







|







 







<
<
<
<
<

|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
427
428
429
430
431
432
433





434
435
436
437
438
439
440
441
442
*************************************************************************
** 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.80 2004/07/24 14:35:59 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
  pParse->rc = SQLITE_OK;
  i = 0;
  pEngine = sqlite3ParserAlloc((void*(*)(int))malloc);
  if( pEngine==0 ){
    sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
    return 1;
  }





  pParse->sLastToken.dyn = 0;
  pParse->zTail = pParse->zSql = zSql;
  while( sqlite3_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;
    switch( tokenType ){

Changes to src/vacuum.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
243
244
245
246
247
248
249

250
251
252
**
*************************************************************************
** This file contains code used to implement the VACUUM command.
**
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.26 2004/06/30 09:49:24 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"

#if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM
/*
** Generate a random name of 20 character in length.
................................................................................
    execSql(db, "DETACH vacuum_db;");
  }
  if( zTemp ){
    sqlite3OsDelete(zTemp);
    sqliteFree(zTemp);
  }
  if( zSql ) sqliteFree( zSql );

#endif
  return rc;
} 







|







 







>


|
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
243
244
245
246
247
248
249
250
251
252
253
**
*************************************************************************
** This file contains code used to implement the VACUUM command.
**
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.27 2004/07/24 14:35:59 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"

#if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM
/*
** Generate a random name of 20 character in length.
................................................................................
    execSql(db, "DETACH vacuum_db;");
  }
  if( zTemp ){
    sqlite3OsDelete(zTemp);
    sqliteFree(zTemp);
  }
  if( zSql ) sqliteFree( zSql );
  sqlite3ResetInternalSchema(db, 0);
#endif
  return rc;
}

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
504
505
506
507
508
509
510




511
512
513






514
515
516
517
518
519
520
....
2279
2280
2281
2282
2283
2284
2285

2286
2287
2288

2289
2290
2291
2292





2293
2294
2295
2296
2297
2298
2299
....
3726
3727
3728
3729
3730
3731
3732

3733
3734
3735
3736
3737
3738
3739
**
** 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.404 2004/07/24 03:30:48 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
#endif
    pOp = &p->aOp[pc];

    /* Only allow tracing if NDEBUG is not defined.
    */
#ifndef NDEBUG
    if( p->trace ){




      sqlite3VdbePrintOp(p->trace, pc, pOp);
    }
#endif







    /* Check to see if we need to simulate an interrupt.  This only happens
    ** if we have a special test build.
    */
#ifdef SQLITE_TEST
    if( sqlite3_interrupt_count>0 ){
      sqlite3_interrupt_count--;
................................................................................
** P2==2 is the recommended pager cache size, and so forth.  P1==0 is
** the main database file and P1==1 is the database file used to store
** temporary tables.
**
** A transaction must be started before executing this opcode.
*/
case OP_SetCookie: {

  assert( pOp->p2<SQLITE_N_BTREE_META );
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( db->aDb[pOp->p1].pBt!=0 );

  assert( pTos>=p->aStack );
  Integerify(pTos);
  /* See note about index shifting on OP_ReadCookie */
  rc = sqlite3BtreeUpdateMeta(db->aDb[pOp->p1].pBt, 1+pOp->p2, (int)pTos->i);





  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  break;
}

/* Opcode: VerifyCookie P1 P2 *
**
................................................................................
case OP_ParseSchema: {
  char *zSql;
  int iDb = pOp->p1;
  const char *zMaster;
  InitData initData;

  assert( iDb>=0 && iDb<db->nDb );

  zMaster = iDb==1 ? TEMP_MASTER_NAME : MASTER_NAME;
  initData.db = db;
  initData.pzErrMsg = &p->zErrMsg;
  zSql = sqlite3MPrintf(
     "SELECT name, rootpage, sql, %d FROM '%q'.%s WHERE %s",
     pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3);
  sqlite3SafetyOff(db);







|







 







>
>
>
>



>
>
>
>
>
>







 







>


|
>



|
>
>
>
>
>







 







>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
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
....
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
....
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
**
** 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.405 2004/07/24 14:35:59 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
#endif
    pOp = &p->aOp[pc];

    /* Only allow tracing if NDEBUG is not defined.
    */
#ifndef NDEBUG
    if( p->trace ){
      if( pc==0 ){
        printf("VDBE Execution Trace:\n");
        sqlite3VdbePrintSql(p);
      }
      sqlite3VdbePrintOp(p->trace, pc, pOp);
    }
#endif
#ifdef SQLITE_TEST
    if( p->trace==0 && pc==0 && sqlite3OsFileExists("vdbe_sqltrace") ){
      sqlite3VdbePrintSql(p);
    }
#endif
      

    /* Check to see if we need to simulate an interrupt.  This only happens
    ** if we have a special test build.
    */
#ifdef SQLITE_TEST
    if( sqlite3_interrupt_count>0 ){
      sqlite3_interrupt_count--;
................................................................................
** P2==2 is the recommended pager cache size, and so forth.  P1==0 is
** the main database file and P1==1 is the database file used to store
** temporary tables.
**
** A transaction must be started before executing this opcode.
*/
case OP_SetCookie: {
  Db *pDb;
  assert( pOp->p2<SQLITE_N_BTREE_META );
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  pDb = &db->aDb[pOp->p1];
  assert( pDb->pBt!=0 );
  assert( pTos>=p->aStack );
  Integerify(pTos);
  /* See note about index shifting on OP_ReadCookie */
  rc = sqlite3BtreeUpdateMeta(pDb->pBt, 1+pOp->p2, (int)pTos->i);
  if( pOp->p2==0 ){
    /* When the schema cookie changes, record the new cookie internally */
    pDb->schema_cookie = pTos->i;
    db->flags |= SQLITE_InternChanges;
  }
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  break;
}

/* Opcode: VerifyCookie P1 P2 *
**
................................................................................
case OP_ParseSchema: {
  char *zSql;
  int iDb = pOp->p1;
  const char *zMaster;
  InitData initData;

  assert( iDb>=0 && iDb<db->nDb );
  if( !DbHasProperty(db, iDb, DB_SchemaLoaded) ) break;
  zMaster = iDb==1 ? TEMP_MASTER_NAME : MASTER_NAME;
  initData.db = db;
  initData.pzErrMsg = &p->zErrMsg;
  zSql = sqlite3MPrintf(
     "SELECT name, rootpage, sql, %d FROM '%q'.%s WHERE %s",
     pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3);
  sqlite3SafetyOff(db);

Changes to src/vdbeInt.h.

363
364
365
366
367
368
369

370
371
372
373
374
375
376
int sqlite3VdbeAggReset(sqlite *, Agg *, KeyInfo *);
void sqlite3VdbeKeylistFree(Keylist*);
void sqliteVdbePopStack(Vdbe*,int);
int sqlite3VdbeCursorMoveto(Cursor*);
#if !defined(NDEBUG) || defined(VDBE_PROFILE)
void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif

int sqlite3VdbeSerialTypeLen(u32);
u32 sqlite3VdbeSerialType(Mem*);
int sqlite3VdbeSerialPut(unsigned char*, Mem*);
int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);

int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);







>







363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
int sqlite3VdbeAggReset(sqlite *, Agg *, KeyInfo *);
void sqlite3VdbeKeylistFree(Keylist*);
void sqliteVdbePopStack(Vdbe*,int);
int sqlite3VdbeCursorMoveto(Cursor*);
#if !defined(NDEBUG) || defined(VDBE_PROFILE)
void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
void sqlite3VdbePrintSql(Vdbe*);
int sqlite3VdbeSerialTypeLen(u32);
u32 sqlite3VdbeSerialType(Mem*);
int sqlite3VdbeSerialPut(unsigned char*, Mem*);
int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);

int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);

Changes to src/vdbeaux.c.

412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
...
516
517
518
519
520
521
522

















523
524
525
526
527
528
529
...
567
568
569
570
571
572
573

574
575
576
577
578
579
580
581
582
583
584
585
586
        strcat(zTemp, zNum);
      }
      zP3 = zTemp;
      break;
    }
    default: {
      zP3 = pOp->p3;
      if( zP3==0 ){
        zP3 = "";
      }
    }
  }
  return zP3;
}

................................................................................
    p->pTos = pMem;
    p->rc = SQLITE_OK;
    p->resOnStack = 1;
    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 sqlite3VdbeExec().  
*/
................................................................................

#ifdef SQLITE_DEBUG
  if( (p->db->flags & SQLITE_VdbeListing)!=0
    || sqlite3OsFileExists("vdbe_explain")
  ){
    int i;
    printf("VDBE Program Listing:\n");

    for(i=0; i<p->nOp; i++){
      sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
    }
  }
  if( sqlite3OsFileExists("vdbe_trace") ){
    printf("VDBE Execution Trace:\n");
    p->trace = stdout;
  }
#endif
  p->pTos = &p->aStack[-1];
  p->pc = -1;
  p->rc = SQLITE_OK;
  p->uniqueCnt = 0;







|







 







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







 







>





<







412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
...
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
...
584
585
586
587
588
589
590
591
592
593
594
595
596

597
598
599
600
601
602
603
        strcat(zTemp, zNum);
      }
      zP3 = zTemp;
      break;
    }
    default: {
      zP3 = pOp->p3;
      if( zP3==0 || pOp->opcode==OP_Noop ){
        zP3 = "";
      }
    }
  }
  return zP3;
}

................................................................................
    p->pTos = pMem;
    p->rc = SQLITE_OK;
    p->resOnStack = 1;
    rc = SQLITE_ROW;
  }
  return rc;
}

/*
** Print the SQL that was used to generate a VDBE program.
*/
void sqlite3VdbePrintSql(Vdbe *p){
#ifdef SQLITE_DEBUG
  int nOp = p->nOp;
  VdbeOp *pOp;
  if( nOp<2 ) return;
  pOp = &p->aOp[nOp-2];
  if( pOp->opcode==OP_Noop && pOp->p3!=0 ){
    const char *z = pOp->p3;
    while( isspace(*z) ) z++;
    printf("SQL: [%s]\n", z);
  }
#endif
}

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

#ifdef SQLITE_DEBUG
  if( (p->db->flags & SQLITE_VdbeListing)!=0
    || sqlite3OsFileExists("vdbe_explain")
  ){
    int i;
    printf("VDBE Program Listing:\n");
    sqlite3VdbePrintSql(p);
    for(i=0; i<p->nOp; i++){
      sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
    }
  }
  if( sqlite3OsFileExists("vdbe_trace") ){

    p->trace = stdout;
  }
#endif
  p->pTos = &p->aStack[-1];
  p->pc = -1;
  p->rc = SQLITE_OK;
  p->uniqueCnt = 0;

Changes to test/misc4.test.

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
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc4.test,v 1.4 2004/07/24 03:30:49 drh Exp $

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

# Prepare a statement that will create a temporary table.  Then do
# a rollback.  Then try to execute the prepared statement.
#
................................................................................
do_test misc4-1.1 {
  db close
  set DB [sqlite3 db test.db]
  execsql {
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(1);
  }


  set sql {CREATE TEMP TABLE t2 AS SELECT * FROM t1}
  set stmt [sqlite3_prepare $DB $sql -1 TAIL]
  execsql {
    BEGIN;
    CREATE TABLE t3(a,b,c);
    INSERT INTO t1 SELECT * FROM t1;
    ROLLBACK;
  }


  sqlite3_step $stmt


  execsql {
    SELECT * FROM temp.t2;
  }
} {1}

# Drop the temporary table, then rerun the prepared  statement to
# recreate it again.  This recreates ticket #807.
#
do_test misc4-1.2 {
  execsql {DROP TABLE t2}
  sqlite3_reset $stmt
  sqlite3_step $stmt
} {SQLITE_ERROR}
do_test misc4-1.3 {
  sqlite3_finalize $stmt
} {SQLITE_SCHEMA}

# Prepare but do not execute various CREATE statements.  Then before
# those statements are executed, try to use the tables, indices, views,
# are triggers that were created.
#







|







 







>
>








>
>

>
>








|




|







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
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc4.test,v 1.5 2004/07/24 14:35:59 drh Exp $

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

# Prepare a statement that will create a temporary table.  Then do
# a rollback.  Then try to execute the prepared statement.
#
................................................................................
do_test misc4-1.1 {
  db close
  set DB [sqlite3 db test.db]
  execsql {
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(1);
  }
} {}
do_test misc4-1.2 {
  set sql {CREATE TEMP TABLE t2 AS SELECT * FROM t1}
  set stmt [sqlite3_prepare $DB $sql -1 TAIL]
  execsql {
    BEGIN;
    CREATE TABLE t3(a,b,c);
    INSERT INTO t1 SELECT * FROM t1;
    ROLLBACK;
  }
} {}
do_test misc4-1.3 {
  sqlite3_step $stmt
} SQLITE_DONE
do_test misc4-1.4 {
  execsql {
    SELECT * FROM temp.t2;
  }
} {1}

# Drop the temporary table, then rerun the prepared  statement to
# recreate it again.  This recreates ticket #807.
#
do_test misc4-1.5 {
  execsql {DROP TABLE t2}
  sqlite3_reset $stmt
  sqlite3_step $stmt
} {SQLITE_ERROR}
do_test misc4-1.6 {
  sqlite3_finalize $stmt
} {SQLITE_SCHEMA}

# Prepare but do not execute various CREATE statements.  Then before
# those statements are executed, try to use the tables, indices, views,
# are triggers that were created.
#