/ Check-in [a05fabd2]
Login

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

Overview
Comment:Attempt to detect when two or more threads try to use the same database at the same time and return an SQLITE_MISUSE error. Also return this error if an attempt is made to use a closed database. (CVS 558)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:a05fabd2df1cb38c555a7b2f31b0ca687db500c2
User & Date: drh 2002-05-10 05:44:56
Context
2002-05-10
13:14
Improvements to the SQLITE_MISUSE detection logic. Also added test cases for this logic, including the new test file "misuse.test". (CVS 559) check-in: f42907ce user: drh tags: trunk
05:44
Attempt to detect when two or more threads try to use the same database at the same time and return an SQLITE_MISUSE error. Also return this error if an attempt is made to use a closed database. (CVS 558) check-in: a05fabd2 user: drh tags: trunk
2002-05-08
21:46
Fix for ticket #35: Ignore any ORDER BY clause on a subquery in a FROM clause. (CVS 557) check-in: 1b0ee944 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
...
328
329
330
331
332
333
334

335
336
337
338
339
340
341
...
355
356
357
358
359
360
361

362
363
364
365
366
367
368
...
429
430
431
432
433
434
435


436
437
438
439
440
441
442
...
522
523
524
525
526
527
528

529
530
531
532

533
534
535
536
537
538
539
...
550
551
552
553
554
555
556

557
558







































559
560
561
562
563
564
565
**
*************************************************************************
** 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.69 2002/04/12 10:08:59 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"

/*
** This is the callback routine for the code that initializes the
** database.  See sqliteInit() below for additional information.
................................................................................
  sqliteHashInit(&db->idxHash, SQLITE_HASH_STRING, 0);
  sqliteHashInit(&db->tblDrop, SQLITE_HASH_POINTER, 0);
  sqliteHashInit(&db->idxDrop, SQLITE_HASH_POINTER, 0);
  sqliteHashInit(&db->aFunc, SQLITE_HASH_STRING, 1);
  sqliteRegisterBuildinFunctions(db);
  db->onError = OE_Default;
  db->priorNewRowid = 0;

  
  /* Open the backend database driver */
  rc = sqliteBtreeOpen(zFilename, mode, MAX_PAGES, &db->pBe);
  if( rc!=SQLITE_OK ){
    switch( rc ){
      default: {
        sqliteSetString(pzErrMsg, "unable to open database: ", zFilename, 0);
................................................................................
    sqlite_close(db);
    sqliteStrRealloc(pzErrMsg);
    return 0;
  }else if( pzErrMsg ){
    sqliteFree(*pzErrMsg);
    *pzErrMsg = 0;
  }

  return db;

no_mem_on_open:
  sqliteSetString(pzErrMsg, "out of memory", 0);
  sqliteStrRealloc(pzErrMsg);
  return 0;
}
................................................................................
}

/*
** Close an existing SQLite database
*/
void sqlite_close(sqlite *db){
  HashElem *i;


  sqliteBtreeClose(db->pBe);
  clearHashTable(db, 0);
  if( db->pBeTemp ){
    sqliteBtreeClose(db->pBeTemp);
  }
  for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
    FuncDef *pFunc, *pNext;
................................................................................
  sqlite_callback xCallback,  /* Invoke this callback routine */
  void *pArg,                 /* First argument to xCallback() */
  char **pzErrMsg             /* Write error messages here */
){
  Parse sParse;

  if( pzErrMsg ) *pzErrMsg = 0;

  if( (db->flags & SQLITE_Initialized)==0 ){
    int rc = sqliteInit(db, pzErrMsg);
    if( rc!=SQLITE_OK ){
      sqliteStrRealloc(pzErrMsg);

      return rc;
    }
  }
  if( db->recursionDepth==0 ){ db->nChange = 0; }
  db->recursionDepth++;
  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
................................................................................
    clearHashTable(db, 0);
  }
  sqliteStrRealloc(pzErrMsg);
  if( sParse.rc==SQLITE_SCHEMA ){
    clearHashTable(db, 1);
  }
  db->recursionDepth--;

  return sParse.rc;
}








































/*
** This routine implements a busy callback that sleeps and tries
** again until a timeout value is reached.  The timeout value is
** an integer number of milliseconds passed in as the first
** argument.
*/







|







 







>







 







>







 







>
>







 







>




>







 







>


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







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
...
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
...
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
...
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
...
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
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
**
*************************************************************************
** 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.70 2002/05/10 05:44:56 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"

/*
** This is the callback routine for the code that initializes the
** database.  See sqliteInit() below for additional information.
................................................................................
  sqliteHashInit(&db->idxHash, SQLITE_HASH_STRING, 0);
  sqliteHashInit(&db->tblDrop, SQLITE_HASH_POINTER, 0);
  sqliteHashInit(&db->idxDrop, SQLITE_HASH_POINTER, 0);
  sqliteHashInit(&db->aFunc, SQLITE_HASH_STRING, 1);
  sqliteRegisterBuildinFunctions(db);
  db->onError = OE_Default;
  db->priorNewRowid = 0;
  db->magic = SQLITE_MAGIC_BUSY;
  
  /* Open the backend database driver */
  rc = sqliteBtreeOpen(zFilename, mode, MAX_PAGES, &db->pBe);
  if( rc!=SQLITE_OK ){
    switch( rc ){
      default: {
        sqliteSetString(pzErrMsg, "unable to open database: ", zFilename, 0);
................................................................................
    sqlite_close(db);
    sqliteStrRealloc(pzErrMsg);
    return 0;
  }else if( pzErrMsg ){
    sqliteFree(*pzErrMsg);
    *pzErrMsg = 0;
  }
  db->magic = SQLITE_MAGIC_OPEN;
  return db;

no_mem_on_open:
  sqliteSetString(pzErrMsg, "out of memory", 0);
  sqliteStrRealloc(pzErrMsg);
  return 0;
}
................................................................................
}

/*
** Close an existing SQLite database
*/
void sqlite_close(sqlite *db){
  HashElem *i;
  if( sqliteSafetyOn(db) ){ return; }
  db->magic = SQLITE_MAGIC_CLOSED;
  sqliteBtreeClose(db->pBe);
  clearHashTable(db, 0);
  if( db->pBeTemp ){
    sqliteBtreeClose(db->pBeTemp);
  }
  for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
    FuncDef *pFunc, *pNext;
................................................................................
  sqlite_callback xCallback,  /* Invoke this callback routine */
  void *pArg,                 /* First argument to xCallback() */
  char **pzErrMsg             /* Write error messages here */
){
  Parse sParse;

  if( pzErrMsg ) *pzErrMsg = 0;
  if( sqliteSafetyOn(db) ){ return SQLITE_MISUSE; }
  if( (db->flags & SQLITE_Initialized)==0 ){
    int rc = sqliteInit(db, pzErrMsg);
    if( rc!=SQLITE_OK ){
      sqliteStrRealloc(pzErrMsg);
      sqliteSafetyOff(db);
      return rc;
    }
  }
  if( db->recursionDepth==0 ){ db->nChange = 0; }
  db->recursionDepth++;
  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
................................................................................
    clearHashTable(db, 0);
  }
  sqliteStrRealloc(pzErrMsg);
  if( sParse.rc==SQLITE_SCHEMA ){
    clearHashTable(db, 1);
  }
  db->recursionDepth--;
  if( sqliteSafetyOff(db) ){ sParse.rc = SQLITE_MISUSE; }
  return sParse.rc;
}

/*
** Change the magic from SQLITE_MAGIC_OPEN to SQLITE_MAGIC_BUSY.
** Return an error (non-zero) if the magic was not SQLITE_MAGIC_OPEN
** when this routine is called.
**
** This routine is a attempt to detect if two threads attempt
** to use the same sqlite* pointer at the same time.  There is a
** race condition so it is possible that the error is not detected.
** But usually the problem will be seen.  The result will be an
** error which can be used to debugging the application that is
** using SQLite incorrectly.
*/
int sqliteSafetyOn(sqlite *db){
  if( db->magic==SQLITE_MAGIC_OPEN ){
    db->magic = SQLITE_MAGIC_BUSY;
    return 0;
  }else{
    db->magic = SQLITE_MAGIC_ERROR;
    db->flags |= SQLITE_Interrupt;
    return 1;
  }
}

/*
** Change the magic from SQLITE_MAGIC_BUSY to SQLITE_MAGIC_OPEN.
** Return an error (non-zero) if the magic was not SQLITE_MAGIC_BUSY
** when this routine is called.
*/
int sqliteSafetyOff(sqlite *db){
  if( db->magic==SQLITE_MAGIC_BUSY ){
    db->magic = SQLITE_MAGIC_OPEN;
    return 0;
  }else{
    db->magic = SQLITE_MAGIC_ERROR;
    db->flags |= SQLITE_Interrupt;
    return 1;
  }
}

/*
** This routine implements a busy callback that sleeps and tries
** again until a timeout value is reached.  The timeout value is
** an integer number of milliseconds passed in as the first
** argument.
*/

Changes to src/sqlite.h.in.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
157
158
159
160
161
162
163

164
165
166
167
168
169
170
**    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.30 2002/04/12 10:08:59 drh Exp $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** The version of the SQLite library.
................................................................................
#define SQLITE_CANTOPEN    14   /* Unable to open the database file */
#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
#define SQLITE_EMPTY       16   /* (Internal Only) Database table is empty */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* Too much data for one row of a table */
#define SQLITE_CONSTRAINT  19   /* Abort due to contraint violation */
#define SQLITE_MISMATCH    20   /* Data type mismatch */


/*
** Each entry in an SQLite table has a unique integer key.  (The key is
** the value of the INTEGER PRIMARY KEY column if there is such a column,
** otherwise the key is generated at random.  The unique key is always
** available as the ROWID, OID, or _ROWID_ column.)  The following routine
** returns the integer key of the most recent insert in the database.







|







 







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
**    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.31 2002/05/10 05:44:56 drh Exp $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** The version of the SQLite library.
................................................................................
#define SQLITE_CANTOPEN    14   /* Unable to open the database file */
#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
#define SQLITE_EMPTY       16   /* (Internal Only) Database table is empty */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* Too much data for one row of a table */
#define SQLITE_CONSTRAINT  19   /* Abort due to contraint violation */
#define SQLITE_MISMATCH    20   /* Data type mismatch */
#define SQLITE_MISUSE      21   /* Library used incorrectly */

/*
** Each entry in an SQLite table has a unique integer key.  (The key is
** the value of the INTEGER PRIMARY KEY column if there is such a column,
** otherwise the key is generated at random.  The unique key is always
** available as the ROWID, OID, or _ROWID_ column.)  The following routine
** returns the integer key of the most recent insert in the database.

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
163
164
165
166
167
168
169

170
171
172
173
174
175
176
...
185
186
187
188
189
190
191










192
193
194
195
196
197
198
...
644
645
646
647
648
649
650


**    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.105 2002/04/12 10:08:59 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
#include <stdio.h>
................................................................................
  Hash idxHash;                 /* All (named) indices indexed by name */
  Hash tblDrop;                 /* Uncommitted DROP TABLEs */
  Hash idxDrop;                 /* Uncommitted DROP INDEXs */
  Hash aFunc;                   /* All functions that can be in SQL exprs */
  int lastRowid;                /* ROWID of most recent insert */
  int priorNewRowid;            /* Last randomly generated ROWID */
  int onError;                  /* Default conflict algorithm */

  int nChange;                  /* Number of rows changed */
  int recursionDepth;           /* Number of nested calls to sqlite_exec() */
};

/*
** Possible values for the sqlite.flags.
*/
................................................................................
                                          /*   the count using a callback. */
#define SQLITE_NullCallback   0x00000080  /* Invoke the callback once if the */
                                          /*   result set is empty */
#define SQLITE_ResultDetails  0x00000100  /* Details added to result set */
#define SQLITE_UnresetViews   0x00000200  /* True if one or more views have */
                                          /*   defined column names */











/*
** Each SQL function is defined by an instance of the following
** structure.  A pointer to this structure is stored in the sqlite.aFunc
** hash table.  When multiple functions have the same name, the hash table
** points to a linked list of these structures.
*/
struct FuncDef {
................................................................................
void sqliteSelectMoveStrings(Select*, int);
Expr *sqliteExprDup(Expr*);
ExprList *sqliteExprListDup(ExprList*);
IdList *sqliteIdListDup(IdList*);
Select *sqliteSelectDup(Select*);
FuncDef *sqliteFindFunction(sqlite*,const char*,int,int,int);
void sqliteRegisterBuildinFunctions(sqlite*);









|







 







>







 







>
>
>
>
>
>
>
>
>
>







 







>
>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
...
655
656
657
658
659
660
661
662
663
**    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.106 2002/05/10 05:44:56 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
#include <stdio.h>
................................................................................
  Hash idxHash;                 /* All (named) indices indexed by name */
  Hash tblDrop;                 /* Uncommitted DROP TABLEs */
  Hash idxDrop;                 /* Uncommitted DROP INDEXs */
  Hash aFunc;                   /* All functions that can be in SQL exprs */
  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() */
};

/*
** Possible values for the sqlite.flags.
*/
................................................................................
                                          /*   the count using a callback. */
#define SQLITE_NullCallback   0x00000080  /* Invoke the callback once if the */
                                          /*   result set is empty */
#define SQLITE_ResultDetails  0x00000100  /* Details added to result set */
#define SQLITE_UnresetViews   0x00000200  /* True if one or more views have */
                                          /*   defined column names */

/*
** Possible values for the sqlite.magic field.
** The numbers are obtained at random and have no special meaning, other
** than being distinct from one another.
*/
#define SQLITE_MAGIC_OPEN     0xa029a697  /* Database is open */
#define SQLITE_MAGIC_CLOSED   0x9f3c2d33  /* Database is closed */
#define SQLITE_MAGIC_BUSY     0xf03b7906  /* Database currently in use */
#define SQLITE_MAGIC_ERROR    0xb5357930  /* An SQLITE_MISUSE error occurred */

/*
** Each SQL function is defined by an instance of the following
** structure.  A pointer to this structure is stored in the sqlite.aFunc
** hash table.  When multiple functions have the same name, the hash table
** points to a linked list of these structures.
*/
struct FuncDef {
................................................................................
void sqliteSelectMoveStrings(Select*, int);
Expr *sqliteExprDup(Expr*);
ExprList *sqliteExprListDup(ExprList*);
IdList *sqliteIdListDup(IdList*);
Select *sqliteSelectDup(Select*);
FuncDef *sqliteFindFunction(sqlite*,const char*,int,int,int);
void sqliteRegisterBuildinFunctions(sqlite*);
int sqliteSafetyOn(sqlite*);
int sqliteSafetyOff(sqlite*);

Changes to src/test2.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
38
39
40
41
42
43
44






45
46
47
48
49
50
51
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the pager.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test2.c,v 1.7 2002/02/02 15:01:16 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

................................................................................
    case SQLITE_INTERRUPT:  zName = "SQLITE_INTERRUPT";   break;
    case SQLITE_IOERR:      zName = "SQLITE_IOERR";       break;
    case SQLITE_CORRUPT:    zName = "SQLITE_CORRUPT";     break;
    case SQLITE_NOTFOUND:   zName = "SQLITE_NOTFOUND";    break;
    case SQLITE_FULL:       zName = "SQLITE_FULL";        break;
    case SQLITE_CANTOPEN:   zName = "SQLITE_CANTOPEN";    break;
    case SQLITE_PROTOCOL:   zName = "SQLITE_PROTOCOL";    break;






    default:                zName = "SQLITE_Unknown";     break;
  }
  return zName;
}

/*
** Usage:   pager_open FILENAME N-PAGE







|







 







>
>
>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the pager.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test2.c,v 1.8 2002/05/10 05:44:56 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

................................................................................
    case SQLITE_INTERRUPT:  zName = "SQLITE_INTERRUPT";   break;
    case SQLITE_IOERR:      zName = "SQLITE_IOERR";       break;
    case SQLITE_CORRUPT:    zName = "SQLITE_CORRUPT";     break;
    case SQLITE_NOTFOUND:   zName = "SQLITE_NOTFOUND";    break;
    case SQLITE_FULL:       zName = "SQLITE_FULL";        break;
    case SQLITE_CANTOPEN:   zName = "SQLITE_CANTOPEN";    break;
    case SQLITE_PROTOCOL:   zName = "SQLITE_PROTOCOL";    break;
    case SQLITE_EMPTY:      zName = "SQLITE_EMPTY";       break;
    case SQLITE_SCHEMA:     zName = "SQLITE_SCHEMA";      break;
    case SQLITE_TOOBIG:     zName = "SQLITE_TOOBIG";      break;
    case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT";  break;
    case SQLITE_MISMATCH:   zName = "SQLITE_MISMATCH";    break;
    case SQLITE_MISUSE:     zName = "SQLITE_MISUSE";      break;
    default:                zName = "SQLITE_Unknown";     break;
  }
  return zName;
}

/*
** Usage:   pager_open FILENAME N-PAGE

Changes to src/util.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1092
1093
1094
1095
1096
1097
1098

1099
1100
1101
1102
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.41 2002/03/06 03:08:26 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
    case SQLITE_CANTOPEN:   z = "unable to open database file";          break;
    case SQLITE_PROTOCOL:   z = "database locking protocol failure";     break;
    case SQLITE_EMPTY:      z = "table contains no data";                break;
    case SQLITE_SCHEMA:     z = "database schema has changed";           break;
    case SQLITE_TOOBIG:     z = "too much data for one table row";       break;
    case SQLITE_CONSTRAINT: z = "constraint failed";                     break;
    case SQLITE_MISMATCH:   z = "datatype mismatch";                     break;

    default:                z = "unknown error";                         break;
  }
  return z;
}







|







 







>




10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.42 2002/05/10 05:44:56 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
    case SQLITE_CANTOPEN:   z = "unable to open database file";          break;
    case SQLITE_PROTOCOL:   z = "database locking protocol failure";     break;
    case SQLITE_EMPTY:      z = "table contains no data";                break;
    case SQLITE_SCHEMA:     z = "database schema has changed";           break;
    case SQLITE_TOOBIG:     z = "too much data for one table row";       break;
    case SQLITE_CONSTRAINT: z = "constraint failed";                     break;
    case SQLITE_MISMATCH:   z = "datatype mismatch";                     break;
    case SQLITE_MISUSE:     z = "SQLite library used incorrectly";       break;
    default:                z = "unknown error";                         break;
  }
  return z;
}

Changes to src/vdbe.c.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
....
1088
1089
1090
1091
1092
1093
1094

1095
1096
1097
1098
1099
1100
1101
....
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
....
1121
1122
1123
1124
1125
1126
1127




1128
1129



1130
1131
1132
1133
1134
1135
1136
....
1573
1574
1575
1576
1577
1578
1579

1580
1581
1582

1583
1584
1585
1586
1587
1588
1589
....
1608
1609
1610
1611
1612
1613
1614

1615
1616
1617

1618
1619
1620
1621
1622
1623
1624
....
3984
3985
3986
3987
3988
3989
3990

3991
3992
3993

3994
3995
3996
3997
3998
3999
4000
....
4650
4651
4652
4653
4654
4655
4656






4657
4658
4659
4660
4661
4662
4663
** type to the other occurs as necessary.
** 
** Most of the code in this file is taken up by the sqliteVdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** $Id: vdbe.c,v 1.139 2002/04/20 14:24:42 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The following global variable is incremented every time a cursor
** moves, either by the OP_MoveTo or the OP_Next opcode.  The test
................................................................................
*/
int sqliteVdbeList(
  Vdbe *p,                   /* The VDBE */
  sqlite_callback xCallback, /* The callback */
  void *pArg,                /* 1st argument to callback */
  char **pzErrMsg            /* Error msg written here */
){

  int i, rc;
  char *azValue[6];
  char zAddr[20];
  char zP1[20];
  char zP2[20];
  char zP3[40];
  static char *azColumnNames[] = {
................................................................................
  if( xCallback==0 ) return 0;
  azValue[0] = zAddr;
  azValue[2] = zP1;
  azValue[3] = zP2;
  azValue[5] = 0;
  rc = SQLITE_OK;
  for(i=0; rc==SQLITE_OK && i<p->nOp; i++){
    if( p->db->flags & SQLITE_Interrupt ){
      p->db->flags &= ~SQLITE_Interrupt;
      sqliteSetString(pzErrMsg, "interrupted", 0);
      rc = SQLITE_INTERRUPT;
      break;
    }
    sprintf(zAddr,"%d",i);
    sprintf(zP1,"%d", p->aOp[i].p1);
    sprintf(zP2,"%d", p->aOp[i].p2);
................................................................................
    if( p->aOp[i].p3type==P3_POINTER ){
      sprintf(zP3, "ptr(%#x)", (int)p->aOp[i].p3);
      azValue[4] = zP3;
    }else{
      azValue[4] = p->aOp[i].p3;
    }
    azValue[1] = zOpName[p->aOp[i].opcode];




    if( xCallback(pArg, 5, azValue, azColumnNames) ){
      rc = SQLITE_ABORT;



    }
  }
  return rc;
}

/*
** The parameters are pointers to the head of two sorted lists
................................................................................
    }
  }
  zStack[p->tos+1] = 0;
  if( xCallback!=0 ){
    if( p->iOffset>0 ){
      p->iOffset--;
    }else{

      if( xCallback(pArg, pOp->p1, &zStack[i], p->azColName)!=0 ){
        rc = SQLITE_ABORT;
      }

      p->nCallback++;
      if( p->iLimit>0 ){
        p->iLimit--;
        if( p->iLimit==0 ){
          pc = pOp->p2 - 1;
        }
      }
................................................................................
** 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( xCallback!=0 && p->nCallback==0 ){

    if( xCallback(pArg, pOp->p1, 0, p->azColName)!=0 ){
      rc = SQLITE_ABORT;
    }

    p->nCallback++;
  }
  if( sqlite_malloc_failed ) goto no_mem;
  break;
}

/* Opcode: Concat P1 P2 P3
................................................................................
case OP_SortCallback: {
  int i = p->tos;
  VERIFY( if( i<0 ) goto not_enough_stack; )
  if( xCallback!=0 ){
    if( p->iOffset>0 ){
      p->iOffset--;
    }else{

      if( xCallback(pArg, pOp->p1, (char**)zStack[i], p->azColName)!=0 ){
        rc = SQLITE_ABORT;
      }

      p->nCallback++;
      if( p->iLimit>0 ){
        p->iLimit--;
        if( p->iLimit==0 ){
          pc = pOp->p2 - 1;
        }
      }
................................................................................
  /* Jump to here if a malloc() fails.  It's hard to get a malloc()
  ** to fail on a modern VM computer, so this code is untested.
  */
no_mem:
  sqliteSetString(pzErrMsg, "out of memory", 0);
  rc = SQLITE_NOMEM;
  goto cleanup;







  /* Jump to here for any other kind of fatal error.  The "rc" variable
  ** should hold the error number.
  */
abort_due_to_error:
  sqliteSetString(pzErrMsg, sqlite_error_string(rc), 0);
  goto cleanup;







|







 







>







 







|
|







 







>
>
>
>


>
>
>







 







>



>







 







>



>







 







>



>







 







>
>
>
>
>
>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
....
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
....
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
....
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
....
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
....
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
....
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
....
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
** type to the other occurs as necessary.
** 
** Most of the code in this file is taken up by the sqliteVdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** $Id: vdbe.c,v 1.140 2002/05/10 05:44:56 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The following global variable is incremented every time a cursor
** moves, either by the OP_MoveTo or the OP_Next opcode.  The test
................................................................................
*/
int sqliteVdbeList(
  Vdbe *p,                   /* The VDBE */
  sqlite_callback xCallback, /* The callback */
  void *pArg,                /* 1st argument to callback */
  char **pzErrMsg            /* Error msg written here */
){
  sqlite *db = p->db;
  int i, rc;
  char *azValue[6];
  char zAddr[20];
  char zP1[20];
  char zP2[20];
  char zP3[40];
  static char *azColumnNames[] = {
................................................................................
  if( xCallback==0 ) return 0;
  azValue[0] = zAddr;
  azValue[2] = zP1;
  azValue[3] = zP2;
  azValue[5] = 0;
  rc = SQLITE_OK;
  for(i=0; rc==SQLITE_OK && i<p->nOp; i++){
    if( db->flags & SQLITE_Interrupt ){
      db->flags &= ~SQLITE_Interrupt;
      sqliteSetString(pzErrMsg, "interrupted", 0);
      rc = SQLITE_INTERRUPT;
      break;
    }
    sprintf(zAddr,"%d",i);
    sprintf(zP1,"%d", p->aOp[i].p1);
    sprintf(zP2,"%d", p->aOp[i].p2);
................................................................................
    if( p->aOp[i].p3type==P3_POINTER ){
      sprintf(zP3, "ptr(%#x)", (int)p->aOp[i].p3);
      azValue[4] = zP3;
    }else{
      azValue[4] = p->aOp[i].p3;
    }
    azValue[1] = zOpName[p->aOp[i].opcode];
    if( sqliteSafetyOff(db) ){
      rc = SQLITE_MISUSE;
      break;
    }
    if( xCallback(pArg, 5, azValue, azColumnNames) ){
      rc = SQLITE_ABORT;
    }
    if( sqliteSafetyOn(db) ){
      rc = SQLITE_MISUSE;
    }
  }
  return rc;
}

/*
** The parameters are pointers to the head of two sorted lists
................................................................................
    }
  }
  zStack[p->tos+1] = 0;
  if( xCallback!=0 ){
    if( p->iOffset>0 ){
      p->iOffset--;
    }else{
      if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; 
      if( xCallback(pArg, pOp->p1, &zStack[i], p->azColName)!=0 ){
        rc = SQLITE_ABORT;
      }
      if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
      p->nCallback++;
      if( p->iLimit>0 ){
        p->iLimit--;
        if( p->iLimit==0 ){
          pc = pOp->p2 - 1;
        }
      }
................................................................................
** 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( xCallback!=0 && p->nCallback==0 ){
    if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; 
    if( xCallback(pArg, 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
................................................................................
case OP_SortCallback: {
  int i = p->tos;
  VERIFY( if( i<0 ) goto not_enough_stack; )
  if( xCallback!=0 ){
    if( p->iOffset>0 ){
      p->iOffset--;
    }else{
      if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
      if( xCallback(pArg, pOp->p1, (char**)zStack[i], p->azColName)!=0 ){
        rc = SQLITE_ABORT;
      }
      if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
      p->nCallback++;
      if( p->iLimit>0 ){
        p->iLimit--;
        if( p->iLimit==0 ){
          pc = pOp->p2 - 1;
        }
      }
................................................................................
  /* Jump to here if a malloc() fails.  It's hard to get a malloc()
  ** to fail on a modern VM computer, so this code is untested.
  */
no_mem:
  sqliteSetString(pzErrMsg, "out of memory", 0);
  rc = SQLITE_NOMEM;
  goto cleanup;

  /* Jump to here for an SQLITE_MISUSE error.
  */
abort_due_to_misuse:
  rc = SQLITE_MISUSE;
  /* Fall thru into abort_due_to_error */

  /* Jump to here for any other kind of fatal error.  The "rc" variable
  ** should hold the error number.
  */
abort_due_to_error:
  sqliteSetString(pzErrMsg, sqlite_error_string(rc), 0);
  goto cleanup;

Changes to www/c_interface.tcl.

1
2
3
4
5
6
7
8
9
10
11
...
182
183
184
185
186
187
188

189
190
191
192
193
194
195
...
290
291
292
293
294
295
296









297
298
299
300
301
302
303
#
# Run this Tcl script to generate the sqlite.html file.
#
set rcsid {$Id: c_interface.tcl,v 1.26 2002/04/12 10:09:00 drh Exp $}

puts {<html>
<head>
  <title>The C language interface to the SQLite library</title>
</head>
<body bgcolor=white>
<h1 align=center>
................................................................................
#define SQLITE_CANTOPEN    14   /* Unable to open the database file */
#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
#define SQLITE_EMPTY       16   /* (Internal Only) Database table is empty */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* Too much data for one row of a table */
#define SQLITE_CONSTRAINT  19   /* Abort due to contraint violation */
#define SQLITE_MISMATCH    20   /* Data type mismatch */

</pre></blockquote>

<p>
The meanings of these various return values are as follows:
</p>

<blockquote>
................................................................................
</p></dd>
<dt>SQLITE_MISMATCH</dt>
<dd><p>This error occurs when there is an attempt to insert non-integer
data into a column labeled INTEGER PRIMARY KEY.  For most columns, SQLite
ignores the data type and allows any kind of data to be stored.  But
an INTEGER PRIMARY KEY column is only allowed to store integer data.
</p></dd>









</dl>
</blockquote>

<h2>The Extended API</h2>

<p>Only the three core routines shown above are required to use
SQLite.  But there are many other functions that provide 



|







 







>







 







>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
...
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
...
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
#
# Run this Tcl script to generate the sqlite.html file.
#
set rcsid {$Id: c_interface.tcl,v 1.27 2002/05/10 05:44:57 drh Exp $}

puts {<html>
<head>
  <title>The C language interface to the SQLite library</title>
</head>
<body bgcolor=white>
<h1 align=center>
................................................................................
#define SQLITE_CANTOPEN    14   /* Unable to open the database file */
#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
#define SQLITE_EMPTY       16   /* (Internal Only) Database table is empty */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* Too much data for one row of a table */
#define SQLITE_CONSTRAINT  19   /* Abort due to contraint violation */
#define SQLITE_MISMATCH    20   /* Data type mismatch */
#define SQLITE_MISUSE      21   /* Library used incorrectly */
</pre></blockquote>

<p>
The meanings of these various return values are as follows:
</p>

<blockquote>
................................................................................
</p></dd>
<dt>SQLITE_MISMATCH</dt>
<dd><p>This error occurs when there is an attempt to insert non-integer
data into a column labeled INTEGER PRIMARY KEY.  For most columns, SQLite
ignores the data type and allows any kind of data to be stored.  But
an INTEGER PRIMARY KEY column is only allowed to store integer data.
</p></dd>
<dt>SQLITE_MISUSE</dt>
<dd><p>This error might occur if one or more of the SQLite API routines
is used incorrectly.  Examples of incorrect usage include calling
<b>sqlite_exec()</b> after the database has been closed using
<b>sqlite_close()</b> or calling <b>sqlite_exec()</b> with the same
database pointer simultaneously from two separate threads.  The
library makes an effort to detect these sorts of problems, but it
cannot detect them with 100% accuracy.
</p></dd>
</dl>
</blockquote>

<h2>The Extended API</h2>

<p>Only the three core routines shown above are required to use
SQLite.  But there are many other functions that provide