SQLite

Check-in [0af3ff3942]
Login

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

Overview
Comment:Minor fixes related to the tests in misuse.test (CVS 1738)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0af3ff39422e02afdfdaf2005ab5eb01b496dc72
User & Date: danielk1977 2004-06-26 09:50:12.000
Context
2004-06-26
10:02
Fix error message returned when a database cannot be opened. (CVS 1739) (check-in: 440bfd2ac5 user: danielk1977 tags: trunk)
09:50
Minor fixes related to the tests in misuse.test (CVS 1738) (check-in: 0af3ff3942 user: danielk1977 tags: trunk)
08:38
Remove the 'nMaster' argument from various pager and btree functions. (CVS 1737) (check-in: 4e20720984 user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/main.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** 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.234 2004/06/26 06:37:07 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** 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.235 2004/06/26 09:50:12 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
454
455
456
457
458
459
460







461
462
463
464
465
466
467
int sqlite3_close(sqlite *db){
  HashElem *i;
  int j;

  if( !db ){
    return SQLITE_OK;
  }








  /* If there are any outstanding VMs, return SQLITE_BUSY. */
  if( db->pVdbe ){
    sqlite3Error(db, SQLITE_BUSY, 
        "Unable to close due to unfinalised statements");
    return SQLITE_BUSY;
  }







>
>
>
>
>
>
>







454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
int sqlite3_close(sqlite *db){
  HashElem *i;
  int j;

  if( !db ){
    return SQLITE_OK;
  }

  if( db->magic!=SQLITE_MAGIC_CLOSED && 
      db->magic!=SQLITE_MAGIC_OPEN &&
      db->magic!=SQLITE_MAGIC_BUSY
  ){
    return SQLITE_MISUSE;
  }

  /* If there are any outstanding VMs, return SQLITE_BUSY. */
  if( db->pVdbe ){
    sqlite3Error(db, SQLITE_BUSY, 
        "Unable to close due to unfinalised statements");
    return SQLITE_BUSY;
  }
833
834
835
836
837
838
839



840
841
842
843
844
845
846
const char *sqlite3_errmsg(sqlite3 *db){
  if( !db || !db->pErr ){
    /* If db is NULL, then assume that a malloc() failed during an
    ** sqlite3_open() call.
    */
    return sqlite3ErrStr(SQLITE_NOMEM);
  }



  if( !sqlite3_value_text(db->pErr) ){
    return sqlite3ErrStr(db->errCode);
  }
  return sqlite3_value_text(db->pErr);
}

/*







>
>
>







840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
const char *sqlite3_errmsg(sqlite3 *db){
  if( !db || !db->pErr ){
    /* If db is NULL, then assume that a malloc() failed during an
    ** sqlite3_open() call.
    */
    return sqlite3ErrStr(SQLITE_NOMEM);
  }
  if( db->magic!=SQLITE_MAGIC_OPEN && db->magic!=SQLITE_MAGIC_BUSY ){
    return sqlite3ErrStr(SQLITE_MISUSE);
  }
  if( !sqlite3_value_text(db->pErr) ){
    return sqlite3ErrStr(db->errCode);
  }
  return sqlite3_value_text(db->pErr);
}

/*
854
855
856
857
858
859
860








861
862



863
864
865
866
867
868
869
  ** &big_endian[1].
  */
  static char outOfMemBe[] = {
    0, 'o', 0, 'u', 0, 't', 0, ' ', 
    0, 'o', 0, 'f', 0, ' ', 
    0, 'm', 0, 'e', 0, 'm', 0, 'o', 0, 'r', 0, 'y', 0, 0, 0
  };









  if( db && db->pErr ){



    if( !sqlite3_value_text16(db->pErr) ){
      sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
          SQLITE_UTF8, SQLITE_STATIC);
    }
    if( sqlite3_value_text16(db->pErr) ){
      return sqlite3_value_text16(db->pErr);
    }







>
>
>
>
>
>
>
>


>
>
>







864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
  ** &big_endian[1].
  */
  static char outOfMemBe[] = {
    0, 'o', 0, 'u', 0, 't', 0, ' ', 
    0, 'o', 0, 'f', 0, ' ', 
    0, 'm', 0, 'e', 0, 'm', 0, 'o', 0, 'r', 0, 'y', 0, 0, 0
  };
  static char misuseBe [] = {
    0, 'l', 0, 'i', 0, 'b', 0, 'r', 0, 'a', 0, 'r', 0, 'y', 0, ' ', 
    0, 'r', 0, 'o', 0, 'u', 0, 't', 0, 'i', 0, 'n', 0, 'e', 0, ' ', 
    0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ', 
    0, 'o', 0, 'u', 0, 't', 0, ' ', 
    0, 'o', 0, 'f', 0, ' ', 
    0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0
  };

  if( db && db->pErr ){
    if( db->magic==SQLITE_MAGIC_ERROR ){
      return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
    }
    if( !sqlite3_value_text16(db->pErr) ){
      sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
          SQLITE_UTF8, SQLITE_STATIC);
    }
    if( sqlite3_value_text16(db->pErr) ){
      return sqlite3_value_text16(db->pErr);
    }
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
  Parse sParse;
  char *zErrMsg = 0;
  int rc = SQLITE_OK;

  assert( ppStmt );
  *ppStmt = 0;
  if( sqlite3SafetyOn(db) ){
    rc = SQLITE_MISUSE;
    goto prepare_out;
  }

  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sqlite3RunParser(&sParse, zSql, &zErrMsg);

  if( db->xTrace && !db->init.busy ){







|
<







943
944
945
946
947
948
949
950

951
952
953
954
955
956
957
  Parse sParse;
  char *zErrMsg = 0;
  int rc = SQLITE_OK;

  assert( ppStmt );
  *ppStmt = 0;
  if( sqlite3SafetyOn(db) ){
    return SQLITE_MISUSE;

  }

  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sqlite3RunParser(&sParse, zSql, &zErrMsg);

  if( db->xTrace && !db->init.busy ){
Changes to src/test1.c.
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
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.88 2004/06/25 12:08:47 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

#if OS_WIN
# define PTR_FMT "%x"
#else
# define PTR_FMT "%p"
#endif

int sqlite3_exec_printf(
  sqlite *db,                   /* An open database */
  const char *sqlFormat,        /* printf-style format string for the SQL */
  sqlite_callback xCallback,    /* Callback function */
  void *pArg,                   /* 1st argument to callback function */
  char **errmsg,                /* Error msg written here */
  ...                           /* Arguments to the format string. */
);
int sqlite3_exec_printf(
  sqlite *db,                   /* An open database */
  const char *sqlFormat,        /* printf-style format string for the SQL */
  sqlite_callback xCallback,    /* Callback function */
  void *pArg,                   /* 1st argument to callback function */
  char **errmsg,                /* Error msg written here */
  ...                           /* Arguments to the format string. */







|













<
<
<
<
<
<
<
<







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
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.89 2004/06/26 09:50:12 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

#if OS_WIN
# define PTR_FMT "%x"
#else
# define PTR_FMT "%p"
#endif









int sqlite3_exec_printf(
  sqlite *db,                   /* An open database */
  const char *sqlFormat,        /* printf-style format string for the SQL */
  sqlite_callback xCallback,    /* Callback function */
  void *pArg,                   /* 1st argument to callback function */
  char **errmsg,                /* Error msg written here */
  ...                           /* Arguments to the format string. */
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
      dstrAppend(p, argv[i], ' ');
    }
  }
  return 0;
}

/*
** Implementation of the x_sqlite3_exec() function.  This function takes
** a single argument and attempts to execute that argument as SQL code.
** This is illegal and should set the SQLITE_MISUSE flag on the database.
**
** 2004-Jan-07:  We have changed this to make it legal to call sqlite3_exec()
** from within a function call.  
** 
** This routine simulates the effect of having two threads attempt to







|







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
      dstrAppend(p, argv[i], ' ');
    }
  }
  return 0;
}

/*
** Implementation of the x_sqlite_exec() function.  This function takes
** a single argument and attempts to execute that argument as SQL code.
** This is illegal and should set the SQLITE_MISUSE flag on the database.
**
** 2004-Jan-07:  We have changed this to make it legal to call sqlite3_exec()
** from within a function call.  
** 
** This routine simulates the effect of having two threads attempt to
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439

/*
** Usage:  sqlite_test_create_function DB
**
** Call the sqlite3_create_function API on the given database in order
** to create a function named "x_coalesce".  This function does the same thing
** as the "coalesce" function.  This function also registers an SQL function
** named "x_sqlite3_exec" that invokes sqlite3_exec().  Invoking sqlite3_exec()
** in this way is illegal recursion and should raise an SQLITE_MISUSE error.
** The effect is similar to trying to use the same database connection from
** two threads at the same time.
**
** The original motivation for this routine was to be able to call the
** sqlite3_create_function function while a query is in progress in order
** to test the SQLITE_MISUSE detection logic.







|







417
418
419
420
421
422
423
424
425
426
427
428
429
430
431

/*
** Usage:  sqlite_test_create_function DB
**
** Call the sqlite3_create_function API on the given database in order
** to create a function named "x_coalesce".  This function does the same thing
** as the "coalesce" function.  This function also registers an SQL function
** named "x_sqlite_exec" that invokes sqlite3_exec().  Invoking sqlite3_exec()
** in this way is illegal recursion and should raise an SQLITE_MISUSE error.
** The effect is similar to trying to use the same database connection from
** two threads at the same time.
**
** The original motivation for this routine was to be able to call the
** sqlite3_create_function function while a query is in progress in order
** to test the SQLITE_MISUSE detection logic.
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME\"", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  sqlite3_create_function(db, "x_coalesce", -1, SQLITE_UTF8, 0, 
      ifnullFunc, 0, 0);
  sqlite3_create_function(db, "x_sqlite3_exec", 1, SQLITE_UTF8, db,
      sqlite3ExecFunc, 0, 0);
  return TCL_OK;
}

/*
** Routines to implement the x_count() aggregate function.
*/







|







442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME\"", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  sqlite3_create_function(db, "x_coalesce", -1, SQLITE_UTF8, 0, 
      ifnullFunc, 0, 0);
  sqlite3_create_function(db, "x_sqlite_exec", 1, SQLITE_UTF8, db,
      sqlite3ExecFunc, 0, 0);
  return TCL_OK;
}

/*
** Routines to implement the x_count() aggregate function.
*/
Changes to test/capi2.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 2003 January 29
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi2.test,v 1.16 2004/06/21 07:36:33 danielk1977 Exp $
#

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

# proc sqlite_step {stmt N VALS COLS} {
#   upvar $VALS vals
#   upvar $COLS cols
#   upvar $N n
#   set vals [list]
#   set cols [list]
# 
#   set n [sqlite3_column_count $stmt]
# 
#   set rc [sqlite3_step $stmt]
#   for {set i 0} {$i < [sqlite3_column_count $stmt]} {incr i} {
#     lappend cols [sqlite3_column_name $stmt $i]
#   }
#   for {set i 0} {$i < [sqlite3_column_count $stmt]} {incr i} {
#     lappend cols [sqlite3_column_decltype $stmt $i]
#   }
# 
#   for {set i 0} {$i < [sqlite3_data_count $stmt]} {incr i} {
#     lappend vals [sqlite3_column_text $stmt $i]
#   }
# 
#   return $rc
# }

# Return the text values from the current row pointed at by STMT as a list.
proc get_row_values {STMT} {
  set VALUES [list]
  for {set i 0} {$i < [sqlite3_data_count $STMT]} {incr i} {
    lappend VALUES [sqlite3_column_text $STMT $i]
  }
  return $VALUES













|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
























20
21
22
23
24
25
26
# 2003 January 29
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi2.test,v 1.17 2004/06/26 09:50:12 danielk1977 Exp $
#

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

























# Return the text values from the current row pointed at by STMT as a list.
proc get_row_values {STMT} {
  set VALUES [list]
  for {set i 0} {$i < [sqlite3_data_count $STMT]} {incr i} {
    lappend VALUES [sqlite3_column_text $STMT $i]
  }
  return $VALUES
Changes to test/crash.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# $Id: crash.test,v 1.4 2004/06/25 06:23:23 danielk1977 Exp $

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

set repeats 100
# set repeats 10













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# $Id: crash.test,v 1.5 2004/06/26 09:50:12 danielk1977 Exp $

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

set repeats 100
# set repeats 10

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# occured.
proc crashsql {crashdelay crashfile sql} {
  set cfile [file join [pwd] $crashfile]

  set f [open crash.tcl w]
  puts $f "sqlite3_crashparams $crashdelay $cfile"
  puts $f "sqlite3 db test.db"
  puts $f "db eval {pragma synchronous = full}"
  puts $f "db eval {pragma cache_size = 10}"
  puts $f "db eval {"
  puts $f   "$sql"
  puts $f "}"
  close $f

  set r [catch {







<







33
34
35
36
37
38
39

40
41
42
43
44
45
46
# occured.
proc crashsql {crashdelay crashfile sql} {
  set cfile [file join [pwd] $crashfile]

  set f [open crash.tcl w]
  puts $f "sqlite3_crashparams $crashdelay $cfile"
  puts $f "sqlite3 db test.db"

  puts $f "db eval {pragma cache_size = 10}"
  puts $f "db eval {"
  puts $f   "$sql"
  puts $f "}"
  close $f

  set r [catch {
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249
#              attached database journal file.
# crash-4.3.*: Test recovery when crash occurs during sync() of the master
#              journal file. 
#
do_test crash-4.0 {
  file delete -force test2.db
  file delete -force test2.db-journal
  sqlite3 db2 test2.db
  execsql {
    pragma default_cache_size = 10;
    pragma default_synchronous = full;
  } db2
  db2 close
  execsql {
    ATTACH 'test2.db' AS aux;

    CREATE TABLE aux.abc2 AS SELECT 2*a as a, 2*b as b, 2*c as c FROM abc;
  }
  expr [file size test2.db] / 1024
} {559}

for {set i 1} {$i < $repeats} {incr i} {
  set sig [signature]







<

<
<
<
<
<

>







227
228
229
230
231
232
233

234





235
236
237
238
239
240
241
242
243
#              attached database journal file.
# crash-4.3.*: Test recovery when crash occurs during sync() of the master
#              journal file. 
#
do_test crash-4.0 {
  file delete -force test2.db
  file delete -force test2.db-journal

  execsql {





    ATTACH 'test2.db' AS aux;
    PRAGMA aux.default_cache_size = 10;
    CREATE TABLE aux.abc2 AS SELECT 2*a as a, 2*b as b, 2*c as c FROM abc;
  }
  expr [file size test2.db] / 1024
} {559}

for {set i 1} {$i < $repeats} {incr i} {
  set sig [signature]
Changes to test/misuse.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
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

163


164
165
166
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the SQLITE_MISUSE detection logic.
# This test file leaks memory and file descriptors.
#
# $Id: misuse.test,v 1.5 2004/06/19 00:16:31 drh Exp $

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


















# Make sure the test logic works
#
do_test misuse-1.1 {
  db close
  catch {file delete -force test2.db}
  set ::DB [sqlite3 db test2.db]
  execsql {
    CREATE TABLE t1(a,b);
    INSERT INTO t1 VALUES(1,2);
  }

  sqlite_exec_printf $::DB {SELECT * FROM t1} {}

} {0 {a b 1 2}}
do_test misuse-1.2 {

  sqlite_exec_printf $::DB {SELECT x_coalesce(NULL,a) AS 'xyz' FROM t1} {}

} {1 {no such function: x_coalesce}}
do_test misuse-1.3 {
  sqlite_create_function $::DB

  sqlite_exec_printf $::DB {SELECT x_coalesce(NULL,a) AS 'xyz' FROM t1} {}

} {0 {xyz 1}}

# Use the x_sqlite_exec() SQL function to simulate the effect of two
# threads trying to use the same database at the same time.
#
# It used to be prohibited to invoke sqlite_exec() from within a function,
# but that has changed.  The following tests used to cause errors but now
# they do not.
#
do_test misuse-1.4 {
  sqlite_exec_printf $::DB {
     SELECT x_sqlite_exec('SELECT * FROM t1') AS xyz;
  } {}

} {0 {xyz {1 2}}}
do_test misuse-1.5 {
  sqlite_exec_printf $::DB {SELECT * FROM t1} {}
} {0 {a b 1 2}}
do_test misuse-1.6 {
  catchsql {
    SELECT * FROM t1
  }
} {0 {1 2}}

# Attempt to register a new SQL function while an sqlite_exec() is active.
#
do_test misuse-2.1 {
  db close
  set ::DB [sqlite3 db test2.db]
  execsql {
    SELECT * FROM t1
  }
} {1 2}
do_test misuse-2.2 {
  sqlite_exec_printf $::DB {SELECT * FROM t1} {}
} {0 {a b 1 2}}
do_test misuse-2.3 {
  set v [catch {
    db eval {SELECT * FROM t1} {} {
      sqlite_create_function $::DB
    }
  } msg]
  lappend v $msg
} {1 {library routine called out of sequence}}
do_test misuse-2.4 {
  sqlite_exec_printf $::DB {SELECT * FROM t1} {}
} {21 {library routine called out of sequence}}
do_test misuse-2.5 {
  catchsql {
    SELECT * FROM t1
  }
} {1 {library routine called out of sequence}}

# Attempt to register a new SQL aggregate while an sqlite_exec() is active.
#
do_test misuse-3.1 {
  db close
  set ::DB [sqlite3 db test2.db]
  execsql {
    SELECT * FROM t1
  }
} {1 2}
do_test misuse-3.2 {
  sqlite_exec_printf $::DB {SELECT * FROM t1} {}
} {0 {a b 1 2}}
do_test misuse-3.3 {
  set v [catch {
    db eval {SELECT * FROM t1} {} {
      sqlite_create_aggregate $::DB
    }
  } msg]
  lappend v $msg
} {1 {library routine called out of sequence}}
do_test misuse-3.4 {
  sqlite_exec_printf $::DB {SELECT * FROM t1} {}
} {21 {library routine called out of sequence}}
do_test misuse-3.5 {
  catchsql {
    SELECT * FROM t1
  }
} {1 {library routine called out of sequence}}

# Attempt to close the database from an sqlite_exec callback.
#


do_test misuse-4.1 {
  db close
  set ::DB [sqlite3 db test2.db]
  execsql {
    SELECT * FROM t1
  }
} {1 2}
do_test misuse-4.2 {
  sqlite_exec_printf $::DB {SELECT * FROM t1} {}
} {0 {a b 1 2}}
do_test misuse-4.3 {
  set v [catch {
    db eval {SELECT * FROM t1} {} {
      sqlite_close $::DB
    }
  } msg]
  lappend v $msg
} {1 {library routine called out of sequence}}
do_test misuse-4.4 {

  sqlite_exec_printf $::DB {SELECT * FROM t1} {}
} {21 {library routine called out of sequence}}
do_test misuse-4.5 {
  catchsql {
    SELECT * FROM t1
  }
} {1 {library routine called out of sequence}}

# Attempt to use a database after it has been closed.
#
do_test misuse-5.1 {
  db close
  set ::DB [sqlite3 db test2.db]
  execsql {
    SELECT * FROM t1
  }
} {1 2}
do_test misuse-5.2 {
  sqlite_exec_printf $::DB {SELECT * FROM t1} {}
} {0 {a b 1 2}}
do_test misuse-5.3 {
  db close

  sqlite_exec_printf $::DB {SELECT * FROM t1} {}


} {21 {library routine called out of sequence}}

finish_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
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the SQLITE_MISUSE detection logic.
# This test file leaks memory and file descriptors.
#
# $Id: misuse.test,v 1.6 2004/06/26 09:50:12 danielk1977 Exp $

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

proc catchsql2 {sql} {
  set r [
    catch {
      set res [list]
      db eval $sql data {
        if { $res==[list] } {
          foreach f $data(*) {lappend res $f}
        }
        foreach f $data(*) {lappend res $data($f)}
      }
      set res
    } msg
  ]
  lappend r $msg
}


# Make sure the test logic works
#
do_test misuse-1.1 {
  db close
  catch {file delete -force test2.db}
  set ::DB [sqlite3 db test2.db]
  execsql {
    CREATE TABLE t1(a,b);
    INSERT INTO t1 VALUES(1,2);
  }
  catchsql2 {
    SELECT * FROM t1
  }
} {0 {a b 1 2}}
do_test misuse-1.2 {
  catchsql2 {
    SELECT x_coalesce(NULL,a) AS 'xyz' FROM t1
  }
} {1 {no such function: x_coalesce}}
do_test misuse-1.3 {
  sqlite3_create_function $::DB
  catchsql2 {
    SELECT x_coalesce(NULL,a) AS 'xyz' FROM t1
  }
} {0 {xyz 1}}

# Use the x_sqlite_exec() SQL function to simulate the effect of two
# threads trying to use the same database at the same time.
#
# It used to be prohibited to invoke sqlite_exec() from within a function,
# but that has changed.  The following tests used to cause errors but now
# they do not.
#
do_test misuse-1.4 {
  catchsql2 {
     SELECT x_sqlite_exec('SELECT * FROM t1') AS xyz;

  } 
} {0 {xyz {1 2}}}
do_test misuse-1.5 {
  catchsql2 {SELECT * FROM t1}
} {0 {a b 1 2}}
do_test misuse-1.6 {
  catchsql {
    SELECT * FROM t1
  }
} {0 {1 2}}

# Attempt to register a new SQL function while an sqlite_exec() is active.
#
do_test misuse-2.1 {
  db close
  set ::DB [sqlite3 db test2.db]
  execsql {
    SELECT * FROM t1
  }
} {1 2}
do_test misuse-2.2 {
  catchsql2 {SELECT * FROM t1}
} {0 {a b 1 2}}
do_test misuse-2.3 {
  set v [catch {
    db eval {SELECT * FROM t1} {} {
      sqlite3_create_function $::DB
    }
  } msg]
  lappend v $msg
} {1 {library routine called out of sequence}}
do_test misuse-2.4 {
  catchsql2 {SELECT * FROM t1}
} {1 {library routine called out of sequence}}
do_test misuse-2.5 {
  catchsql {
    SELECT * FROM t1
  }
} {1 {library routine called out of sequence}}

# Attempt to register a new SQL aggregate while an sqlite_exec() is active.
#
do_test misuse-3.1 {
  db close
  set ::DB [sqlite3 db test2.db]
  execsql {
    SELECT * FROM t1
  }
} {1 2}
do_test misuse-3.2 {
  catchsql2 {SELECT * FROM t1}
} {0 {a b 1 2}}
do_test misuse-3.3 {
  set v [catch {
    db eval {SELECT * FROM t1} {} {
      sqlite3_create_aggregate $::DB
    }
  } msg]
  lappend v $msg
} {1 {library routine called out of sequence}}
do_test misuse-3.4 {
  catchsql2 {SELECT * FROM t1}
} {1 {library routine called out of sequence}}
do_test misuse-3.5 {
  catchsql {
    SELECT * FROM t1
  }
} {1 {library routine called out of sequence}}

# Attempt to close the database from an sqlite_exec callback.
#
# Update for v3: The db cannot be closed because there are active
# VMs. The sqlite3_close call would return SQLITE_BUSY.
do_test misuse-4.1 {
  db close
  set ::DB [sqlite3 db test2.db]
  execsql {
    SELECT * FROM t1
  }
} {1 2}
do_test misuse-4.2 {
  catchsql2 {SELECT * FROM t1}
} {0 {a b 1 2}}
do_test misuse-4.3 {
  set v [catch {
    db eval {SELECT * FROM t1} {} {
      set r [sqlite3_close $::DB]
    }
  } msg]
  lappend v $msg $r
} {0 {} SQLITE_BUSY}
do_test misuse-4.4 {
  sqlite3_close $::DB
  catchsql2 {SELECT * FROM t1}
} {1 {library routine called out of sequence}}
do_test misuse-4.5 {
  catchsql {
    SELECT * FROM t1
  }
} {1 {library routine called out of sequence}}

# Attempt to use a database after it has been closed.
#
do_test misuse-5.1 {
  db close
  set ::DB [sqlite3 db test2.db]
  execsql {
    SELECT * FROM t1
  }
} {1 2}
do_test misuse-5.2 {
  catchsql2 {SELECT * FROM t1}
} {0 {a b 1 2}}
do_test misuse-5.3 {
  db close
  set r [catch {
    sqlite3_prepare $::DB {SELECT * FROM t1} -1 TAIL
  } msg]
  lappend r $msg
} {1 {(21) library routine called out of sequence}}

finish_test