SQLite

Check-in [4f5e253082]
Login

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

Overview
Comment:(1) Vdbe makes a copy of column types. (2) Don't invalidate other cursors when a statement or transaction is rolled back. (3) Update capi2.test for the new API. (CVS 1597)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4f5e2530829ef91753b083b5f2a1d7332e311cb6
User & Date: danielk1977 2004-06-15 02:44:19.000
Context
2004-06-15
11:40
Minor bugfixes and test case adjustments for version 2 test cases to work with version 3. (CVS 1598) (check-in: e21a181376 user: danielk1977 tags: trunk)
02:44
(1) Vdbe makes a copy of column types. (2) Don't invalidate other cursors when a statement or transaction is rolled back. (3) Update capi2.test for the new API. (CVS 1597) (check-in: 4f5e253082 user: danielk1977 tags: trunk)
02:13
Update comments in btree.c. No changes to code. (CVS 1596) (check-in: 1c6a070635 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/btree.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
** 2004 April 6
**
** 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.
**
*************************************************************************
** $Id: btree.c,v 1.168 2004/06/15 02:13:27 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
** 2004 April 6
**
** 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.
**
*************************************************************************
** $Id: btree.c,v 1.169 2004/06/15 02:44:19 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
1279
1280
1281
1282
1283
1284
1285

















1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301

1302
1303
1304
1305
1306
1307
1308
  }
  pBt->inTrans = TRANS_NONE;
  pBt->inStmt = 0;
  unlockBtreeIfUnused(pBt);
  return rc;
}


















/*
** Invalidate all cursors
*/
static void invalidateCursors(Btree *pBt){
  BtCursor *pCur;
  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
    MemPage *pPage = pCur->pPage;
    if( pPage /* && !pPage->isInit */ ){
      pageIntegrity(pPage);
      releasePage(pPage);
      pCur->pPage = 0;
      pCur->isValid = 0;
      pCur->status = SQLITE_ABORT;
    }
  }
}


#ifdef SQLITE_TEST
/*
** Print debugging information about all cursors to standard output.
*/
void sqlite3BtreeCursorList(Btree *pBt){
  BtCursor *pCur;







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
















>







1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
  }
  pBt->inTrans = TRANS_NONE;
  pBt->inStmt = 0;
  unlockBtreeIfUnused(pBt);
  return rc;
}

#ifndef NDEBUG
/*
** Return the number of write-cursors open on this handle. This is for use
** in assert() expressions, so it is only compiled if NDEBUG is not
** defined.
*/
static int countWriteCursors(Btree *pBt){
  BtCursor *pCur;
  int r = 0;
  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
    if( pCur->wrFlag ) r++;
  }
  return r;
}
#endif

#if 0
/*
** Invalidate all cursors
*/
static void invalidateCursors(Btree *pBt){
  BtCursor *pCur;
  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
    MemPage *pPage = pCur->pPage;
    if( pPage /* && !pPage->isInit */ ){
      pageIntegrity(pPage);
      releasePage(pPage);
      pCur->pPage = 0;
      pCur->isValid = 0;
      pCur->status = SQLITE_ABORT;
    }
  }
}
#endif

#ifdef SQLITE_TEST
/*
** Print debugging information about all cursors to standard output.
*/
void sqlite3BtreeCursorList(Btree *pBt){
  BtCursor *pCur;
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
    rc = sqlite3pager_rollback(pBt->pPager);
    /* The rollback may have destroyed the pPage1->aData value.  So
    ** call getPage() on page 1 again to make sure pPage1->aData is
    ** set correctly. */
    if( getPage(pBt, 1, &pPage1)==SQLITE_OK ){
      releasePage(pPage1);
    }
    invalidateCursors(pBt);
  }
  pBt->inTrans = TRANS_NONE;
  pBt->inStmt = 0;
  unlockBtreeIfUnused(pBt);
  return rc;
}








|







1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
    rc = sqlite3pager_rollback(pBt->pPager);
    /* The rollback may have destroyed the pPage1->aData value.  So
    ** call getPage() on page 1 again to make sure pPage1->aData is
    ** set correctly. */
    if( getPage(pBt, 1, &pPage1)==SQLITE_OK ){
      releasePage(pPage1);
    }
    assert( countWriteCursors(pBt)==0 );
  }
  pBt->inTrans = TRANS_NONE;
  pBt->inStmt = 0;
  unlockBtreeIfUnused(pBt);
  return rc;
}

1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
** to use a cursor that was open at the beginning of this operation
** will result in an error.
*/
int sqlite3BtreeRollbackStmt(Btree *pBt){
  int rc;
  if( pBt->inStmt==0 || pBt->readOnly ) return SQLITE_OK;
  rc = sqlite3pager_stmt_rollback(pBt->pPager);
  invalidateCursors(pBt);
  pBt->inStmt = 0;
  return rc;
}

/*
** Default key comparison function to be used if no comparison function
** is specified on the sqlite3BtreeCursor() call.







|







1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
** to use a cursor that was open at the beginning of this operation
** will result in an error.
*/
int sqlite3BtreeRollbackStmt(Btree *pBt){
  int rc;
  if( pBt->inStmt==0 || pBt->readOnly ) return SQLITE_OK;
  rc = sqlite3pager_stmt_rollback(pBt->pPager);
  assert( countWriteCursors(pBt)==0 );
  pBt->inStmt = 0;
  return rc;
}

/*
** Default key comparison function to be used if no comparison function
** is specified on the sqlite3BtreeCursor() call.
Changes to src/select.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.189 2004/06/12 09:25:18 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.190 2004/06/15 02:44:19 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
640
641
642
643
644
645
646

647
648
649
650
651
652
653
    pTab = pTabList->a[j].pTab;
    if( iCol<0 ) iCol = pTab->iPKey;
    assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
    if( iCol<0 ){
      zType = "INTEGER";
    }else{
      zType = pTab->aCol[iCol].zType;

    }
  }else{
    switch( sqlite3ExprType(pExpr) ){
      case SQLITE_AFF_TEXT:     zType = "TEXT";    break;
      case SQLITE_AFF_NUMERIC:  zType = "NUMERIC"; break;
      default:                  zType = "ANY";     break;
    }







>







640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
    pTab = pTabList->a[j].pTab;
    if( iCol<0 ) iCol = pTab->iPKey;
    assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
    if( iCol<0 ){
      zType = "INTEGER";
    }else{
      zType = pTab->aCol[iCol].zType;
      if( !zType ) zType = "";
    }
  }else{
    switch( sqlite3ExprType(pExpr) ){
      case SQLITE_AFF_TEXT:     zType = "TEXT";    break;
      case SQLITE_AFF_NUMERIC:  zType = "NUMERIC"; break;
      default:                  zType = "ANY";     break;
    }
666
667
668
669
670
671
672



673
674
675
676
677
678
679
680
){
  Vdbe *v = pParse->pVdbe;
  int i;
  for(i=0; i<pEList->nExpr; i++){
    Expr *p = pEList->a[i].pExpr;
    const char *zType = columnType(pParse, pTabList, p);
    if( p==0 ) continue;



    sqlite3VdbeSetColName(v, i+pEList->nExpr, zType, P3_STATIC);
  }
}

/*
** Generate code that will tell the VDBE the names of columns
** in the result set.  This information is used to provide the
** azCol[] values in the callback.







>
>
>
|







667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
){
  Vdbe *v = pParse->pVdbe;
  int i;
  for(i=0; i<pEList->nExpr; i++){
    Expr *p = pEList->a[i].pExpr;
    const char *zType = columnType(pParse, pTabList, p);
    if( p==0 ) continue;
    /* The vdbe must make it's own copy of the column-type, in case the 
    ** schema is reset before this virtual machine is deleted.
    */
    sqlite3VdbeSetColName(v, i+pEList->nExpr, zType, strlen(zType));
  }
}

/*
** Generate code that will tell the VDBE the names of columns
** in the result set.  This information is used to provide the
** azCol[] values in the callback.
Changes to src/test1.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    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.76 2004/06/12 09:25:23 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>








|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    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.77 2004/06/15 02:44:19 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;

  rc = sqlite3_finalize(pStmt);
  Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
  if( rc ){
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:  sqlite3_reset  STMT 
**
** Finalize a statement handle.







<
<
<







769
770
771
772
773
774
775



776
777
778
779
780
781
782
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;

  rc = sqlite3_finalize(pStmt);
  Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);



  return TCL_OK;
}

/*
** Usage:  sqlite3_reset  STMT 
**
** Finalize a statement handle.
805
806
807
808
809
810
811
812
813
814

815
















816
817
818
819
820
821
822
  if( rc ){
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:  sqlite3_reset   VM 
**
** Reset a virtual machine and prepare it to be run again.

*/

















/*
** This is the "static_bind_value" that variables are bound to when
** the FLAG option of sqlite3_bind is "static"
*/
static char *sqlite_static_bind_value = 0;








|

|
>

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







802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
  if( rc ){
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:  sqlite3_changes DB
**
** Return the number of changes made to the database by the last SQL
** execution.
*/
static int test_changes(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3 *db;
  if( objc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"",
       Tcl_GetString(objv[0]), " DB", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_changes(db)));
  return TCL_OK;
}

/*
** This is the "static_bind_value" that variables are bound to when
** the FLAG option of sqlite3_bind is "static"
*/
static char *sqlite_static_bind_value = 0;

1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
       Tcl_GetString(objv[0]), " STMT", 0);
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  rc = sqlite3_step(pStmt);

  if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR;
  Tcl_SetResult(interp, (char *)errorName(rc), 0);
  return TCL_OK;
}

/*
** Usage: sqlite3_column_count STMT 
**







|







1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
       Tcl_GetString(objv[0]), " STMT", 0);
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  rc = sqlite3_step(pStmt);

  /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; */
  Tcl_SetResult(interp, (char *)errorName(rc), 0);
  return TCL_OK;
}

/*
** Usage: sqlite3_column_count STMT 
**
1949
1950
1951
1952
1953
1954
1955

1956
1957
1958
1959
1960
1961
1962
1963
     { "sqlite3_open",                  test_open          ,0 },
     { "sqlite3_open16",                test_open16        ,0 },

     { "sqlite3_prepare",               test_prepare       ,0 },
     { "sqlite3_prepare16",             test_prepare16     ,0 },
     { "sqlite3_finalize",              test_finalize      ,0 },
     { "sqlite3_reset",                 test_reset         ,0 },

     { "sqlite3_step",                  test_step,0 },

     /* sqlite3_column_*() API */
     { "sqlite3_column_count",          test_column_count  ,0 },
     { "sqlite3_data_count",            test_data_count    ,0 },
     { "sqlite3_column_type",           test_column_type   ,0 },
     { "sqlite3_column_blob",           test_column_blob   ,0 },
     { "sqlite3_column_double",         test_column_double ,0 },







>
|







1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
     { "sqlite3_open",                  test_open          ,0 },
     { "sqlite3_open16",                test_open16        ,0 },

     { "sqlite3_prepare",               test_prepare       ,0 },
     { "sqlite3_prepare16",             test_prepare16     ,0 },
     { "sqlite3_finalize",              test_finalize      ,0 },
     { "sqlite3_reset",                 test_reset         ,0 },
     { "sqlite3_changes",               test_changes       ,0 },
     { "sqlite3_step",                  test_step          ,0 },

     /* sqlite3_column_*() API */
     { "sqlite3_column_count",          test_column_count  ,0 },
     { "sqlite3_data_count",            test_data_count    ,0 },
     { "sqlite3_column_type",           test_column_type   ,0 },
     { "sqlite3_column_blob",           test_column_blob   ,0 },
     { "sqlite3_column_double",         test_column_double ,0 },
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
51
52
53
54
55





56


57

58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80


81
82
83
84


85
86
87
88
89
90
91
92
93
94
95
96
97


98
99
100
101
102
103
104
105
106
107
108
# 2003 January 29
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi2.test,v 1.12 2004/05/21 10:08:55 danielk1977 Exp $
#

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





















































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





do_test capi2-1.9 {


  list $N $VALUES $COLNAMES

} {0 {} {}}

do_test capi2-1.10 {
  sqlite3_finalize $VM
} {}

# Check to make sure that the "tail" of a multi-statement SQL script
# is returned by sqlite3_prepare.
#
do_test capi2-2.1 {
  set SQL {
    SELECT name, rowid FROM sqlite_master;
    SELECT name, rowid FROM sqlite_temp_master;
    -- A comment at the end
  }
  set VM [sqlite3_prepare $DB $SQL -1 SQL]
  set SQL
} {
    SELECT name, rowid FROM sqlite_temp_master;
    -- A comment at the end
  }
do_test capi2-2.2 {
  set r [sqlite_step $VM n val colname]
  lappend r $n $val $colname


} {SQLITE_ROW 2 {t1 1} {name rowid text INTEGER}}
do_test capi2-2.3 {
  set r [sqlite_step $VM n val colname]
  lappend r $n $val $colname


} {SQLITE_DONE 2 {} {name rowid text INTEGER}}
do_test capi2-2.4 {
  sqlite3_finalize $VM
} {}
do_test capi2-2.5 {
  set VM [sqlite3_prepare $DB $SQL -1 SQL]
  set SQL
} {
    -- A comment at the end
  }
do_test capi2-2.6 {
  set r [sqlite_step $VM n val colname]
  lappend r $n $val $colname


} {SQLITE_DONE 2 {} {name rowid text INTEGER}}
do_test capi2-2.7 {
  sqlite3_finalize $VM
} {}
do_test capi2-2.8 {
  set VM [sqlite3_prepare $DB $SQL -1 SQL]
  list $SQL $VM
} {{} {}}

# Check the error handling.
#













|




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











|


|


|


|


<
<
<
|


|


<
<
<
|

>
>
>
>
>

>
>
|
>
|
>
|

|

















|
|
>
>


|
|
>
>



|







|
|
>
>



|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93



94
95
96
97
98
99



100
101
102
103
104
105
106
107
108
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
# 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.13 2004/06/15 02:44:20 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
}

# Return the column names followed by declaration types for the result set
# of the SQL statement STMT.
#
# i.e. for:
# CREATE TABLE abc(a text, b integer); 
# SELECT * FROM abc;
#
# The result is {a b text integer}
proc get_column_names {STMT} {
  set VALUES [list]
  for {set i 0} {$i < [sqlite3_column_count $STMT]} {incr i} {
    lappend VALUES [sqlite3_column_name $STMT $i]
  }
  for {set i 0} {$i < [sqlite3_column_count $STMT]} {incr i} {
    lappend VALUES [sqlite3_column_decltype $STMT $i]
  }
  return $VALUES
}

# Check basic functionality
#
do_test capi2-1.1 {
  db close
  set DB [sqlite db test.db]
  execsql {CREATE TABLE t1(a,b,c)}
  set VM [sqlite3_prepare $DB {SELECT name, rowid FROM sqlite_master} -1 TAIL]
  set TAIL
} {}
do_test capi2-1.2 {
  sqlite3_step $VM
} {SQLITE_ROW}
do_test capi2-1.3 {
  sqlite3_data_count $VM
} {2}
do_test capi2-1.4 {
  get_row_values $VM
} {t1 1}
do_test capi2-1.5 {
  get_column_names $VM
} {name rowid text INTEGER}
do_test capi2-1.6 {



  sqlite3_step $VM 
} {SQLITE_DONE}
do_test capi2-1.7 {
  list [sqlite3_column_count $VM] [get_row_values $VM] [get_column_names $VM]
} {2 {} {name rowid text INTEGER}}
do_test capi2-1.8 {



  sqlite3_step $VM
} {SQLITE_MISUSE}

# Update: In v2, once SQLITE_MISUSE is returned the statement handle cannot
# be interrogated for more information. However in v3, since the column
# count, names and types are determined at compile time, these are still
# accessible after an SQLITE_MISUSE error.
do_test capi2-1.9 {
  list [sqlite3_column_count $VM] [get_row_values $VM] [get_column_names $VM]
} {2 {} {name rowid text INTEGER}}
do_test capi2-1.10 {
  sqlite3_data_count $VM
} {0}

do_test capi2-1.11 {
  sqlite3_finalize $VM
} {SQLITE_OK}

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

# Check the error handling.
#
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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215



216
217
218
219
220
221
222
223
224



225
226
227
228
229
230
231
232
233



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248



249
250
251



252
253
254



255
256
257



258
259
260



261
262
263



264
265
266



267
268
269
270
271
272



273
274
275
276
277
278



279
280
281



282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303




304
305



306
307
308
309
310
311



312
313
314
315
316
317



318
319
320
321
322
323



324
325
326
327
328
329



330
331
332
333
334
335



336
337
338
339
340
341
342



343
344
345
346
347
348
349



350
351
352
353
354
355



356
357
358
359
360
361



362
363
364
365
366
367



368
369
370
371
372
373



374
375
376
377
378
379
380
381
382



383
384
385
386
387
388
389
390
391



392
393
394
395
396
397
398
399
400
401
402
do_test capi2-3.6 {
  set rc [catch {
      sqlite3_prepare $DB {select 5/0} -1 TAIL
  } VM]
  lappend rc $TAIL
} {0 {}}
do_test capi2-3.7 {
  set N {}
  set VALUE {}
  set COLNAME {}
  list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_ROW 1 {{}} {5/0 NUMERIC}}
do_test capi2-3.8 {
  sqlite3_finalize $VM
} {}
do_test capi2-3.9 {
  execsql {CREATE UNIQUE INDEX i1 ON t1(a)}
  set VM [sqlite3_prepare $DB {INSERT INTO t1 VALUES(1,2,3)} -1 TAIL]
  set TAIL
} {}
do_test capi2-3.9b {db changes} {0}
do_test capi2-3.10 {
  set N {}
  set VALUE {}
  set COLNAME {}
  list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_DONE 0 {} {}}



do_test capi2-3.10b {db changes} {1}
do_test capi2-3.11 {
  sqlite3_finalize $VM
} {}
do_test capi2-3.11b {db changes} {1}
do_test capi2-3.12 {
  list [catch {sqlite3_finalize $VM} msg] [set msg]
} {1 {(21) library routine called out of sequence}}

do_test capi2-3.13 {
  set VM [sqlite3_prepare $DB {INSERT INTO t1 VALUES(1,3,4)} -1 TAIL]
  list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ERROR 0 {} {}}
do_test capi2-3.13b {db changes} {0}
do_test capi2-3.14 {
  list [catch {sqlite3_finalize $VM} msg] [set msg]
} {1 {(19) column a is not unique}}
do_test capi2-3.15 {
  set VM [sqlite3_prepare $DB {CREATE TABLE t2(a NOT NULL, b)} -1 TAIL]
  set TAIL
} {}
do_test capi2-3.16 {
  list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_DONE 0 {} {}}
do_test capi2-3.17 {
  list [catch {sqlite3_finalize $VM} msg] [set msg]
} {0 {}}
do_test capi2-3.18 {
  set VM [sqlite3_prepare $DB {INSERT INTO t2 VALUES(NULL,2)} -1 TAIL]
  list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ERROR 0 {} {}}
do_test capi2-3.19 {
  list [catch {sqlite3_finalize $VM} msg] [set msg]
} {1 {(19) t2.a may not be NULL}}

# Two or more virtual machines exists at the same time.
#
do_test capi2-4.1 {
  set VM1 [sqlite3_prepare $DB {INSERT INTO t2 VALUES(1,2)} -1 TAIL]
  set TAIL
} {}
do_test capi2-4.2 {
  set VM2 [sqlite3_prepare $DB {INSERT INTO t2 VALUES(2,3)} -1 TAIL]
  set TAIL
} {}
do_test capi2-4.3 {
  set VM3 [sqlite3_prepare $DB {INSERT INTO t2 VALUES(3,4)} -1 TAIL]
  set TAIL
} {}
do_test capi2-4.4 {
  list [sqlite_step $VM2 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_DONE 0 {} {}}
do_test capi2-4.5 {
  execsql {SELECT * FROM t2 ORDER BY a}
} {2 3}
do_test capi2-4.6 {
  list [catch {sqlite3_finalize $VM2} msg] [set msg]
} {0 {}}  
do_test capi2-4.7 {
  list [sqlite_step $VM3 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_DONE 0 {} {}}
do_test capi2-4.8 {
  execsql {SELECT * FROM t2 ORDER BY a}
} {2 3 3 4}
do_test capi2-4.9 {
  list [catch {sqlite3_finalize $VM3} msg] [set msg]
} {0 {}}  
do_test capi2-4.10 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_DONE 0 {} {}}
do_test capi2-4.11 {
  execsql {SELECT * FROM t2 ORDER BY a}
} {1 2 2 3 3 4}
do_test capi2-4.12 {
  list [catch {sqlite3_finalize $VM1} msg] [set msg]
} {0 {}}  

# Interleaved SELECTs
#
do_test capi2-5.1 {
  set VM1 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL]
  set VM2 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL]
  set VM3 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL]
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 2 {2 3} {a b {} {}}}
do_test capi2-5.2 {
  list [sqlite_step $VM2 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 2 {2 3} {a b {} {}}}
do_test capi2-5.3 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 2 {3 4} {a b {} {}}}
do_test capi2-5.4 {
  list [sqlite_step $VM3 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 2 {2 3} {a b {} {}}}
do_test capi2-5.5 {
  list [sqlite_step $VM3 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 2 {3 4} {a b {} {}}}
do_test capi2-5.6 {
  list [sqlite_step $VM3 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 2 {1 2} {a b {} {}}}
do_test capi2-5.7 {
  list [sqlite_step $VM3 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_DONE 2 {} {a b {} {}}}
do_test capi2-5.8 {
  list [catch {sqlite3_finalize $VM3} msg] [set msg]
} {0 {}}  
do_test capi2-5.9 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 2 {1 2} {a b {} {}}}
do_test capi2-5.10 {
  list [catch {sqlite3_finalize $VM1} msg] [set msg]
} {0 {}}  
do_test capi2-5.11 {
  list [sqlite_step $VM2 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 2 {3 4} {a b {} {}}}
do_test capi2-5.12 {
  list [sqlite_step $VM2 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 2 {1 2} {a b {} {}}}
do_test capi2-5.11 {
  list [catch {sqlite3_finalize $VM2} msg] [set msg]
} {0 {}}  

# Check for proper SQLITE_BUSY returns.
#
do_test capi2-6.1 {
  execsql {
    BEGIN;
    CREATE TABLE t3(x counter);
    INSERT INTO t3 VALUES(1);
    INSERT INTO t3 VALUES(2);
    INSERT INTO t3 SELECT x+2 FROM t3;
    INSERT INTO t3 SELECT x+4 FROM t3;
    INSERT INTO t3 SELECT x+8 FROM t3;
    COMMIT;
  }
  set VM1 [sqlite3_prepare $DB {SELECT * FROM t3} -1 TAIL]
  sqlite db2 test.db
  execsql {BEGIN} db2
} {}




do_test capi2-6.2 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_BUSY 0 {} {}}
do_test capi2-6.3 {
  execsql {COMMIT} db2
} {}
do_test capi2-6.4 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 1 1 {x counter}}
do_test capi2-6.5 {
  catchsql {BEGIN} db2
} {1 {database is locked}}
do_test capi2-6.6 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 1 2 {x counter}}
do_test capi2-6.7 {
  execsql {SELECT * FROM t2} db2
} {2 3 3 4 1 2}
do_test capi2-6.8 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 1 3 {x counter}}
do_test capi2-6.9 {
  execsql {SELECT * FROM t2} 
} {2 3 3 4 1 2}
do_test capi2-6.10 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 1 4 {x counter}}
do_test capi2-6.11 {
  execsql {BEGIN}
} {}
do_test capi2-6.12 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 1 5 {x counter}}
# execsql {pragma vdbe_trace=on}
do_test capi2-6.13 {
  catchsql {UPDATE t3 SET x=x+1}
} {1 {database table is locked}}
do_test capi2-6.14 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 1 6 {x counter}}
# puts [list [catch {sqlite3_finalize $VM1} msg] [set msg]]; exit
do_test capi2-6.15 {
  execsql {SELECT * FROM t1}
} {1 2 3}
do_test capi2-6.16 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 1 7 {x counter}}
do_test capi2-6.17 {
  catchsql {UPDATE t1 SET b=b+1}
} {0 {}}
do_test capi2-6.18 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 1 8 {x counter}}
do_test capi2-6.19 {
  execsql {SELECT * FROM t1}
} {1 3 3}
do_test capi2-6.20 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 1 9 {x counter}}
do_test capi2-6.21 {
  execsql {ROLLBACK; SELECT * FROM t1}
} {1 2 3}
do_test capi2-6.22 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 1 10 {x counter}}
do_test capi2-6.23 {
  execsql {BEGIN TRANSACTION ON CONFLICT ROLLBACK;}
} {}
do_test capi2-6.24 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 1 11 {x counter}}
do_test capi2-6.25 {
  execsql {
    INSERT INTO t1 VALUES(2,3,4);
    SELECT * FROM t1;
  }
} {1 2 3 2 3 4}
do_test capi2-6.26 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 1 12 {x counter}}
do_test capi2-6.27 {
  catchsql {
    INSERT INTO t1 VALUES(2,4,5);
    SELECT * FROM t1;
  }
} {1 {column a is not unique}}
do_test capi2-6.28 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]



} {SQLITE_ROW 1 13 {x counter}}
do_test capi2-6.99 {
  list [catch {sqlite3_finalize $VM1} msg] [set msg]
} {0 {}}
catchsql {ROLLBACK}

do_test capi2-7.1 {
  stepsql $DB {
    SELECT * FROM t1
  }
} {0 1 2 3}







|
|
|
|



|







|
|
|
|

>
>
>
|


|
|

|
<
>


|
>
>
>



|
|





|
>
>
>


|
|


|
>
>
>


|
|
















|
>
>
>





|
|

|
>
>
>





|
|

|
>
>
>





|
|







|
>
>
>


|
>
>
>


|
>
>
>


|
>
>
>


|
>
>
>


|
>
>
>


|
>
>
>


|
|

|
>
>
>


|
|

|
>
>
>


|
>
>
>


|
|


















>
>
>
>
|
|
>
>
>
|




|
>
>
>


|


|
>
>
>





|
>
>
>





|
>
>
>





|
>
>
>

<




|
>
>
>

<




|
>
>
>





|
>
>
>





|
>
>
>





|
>
>
>


|


|
>
>
>








|
>
>
>








|
>
>
>


|
|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470

471
472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
do_test capi2-3.6 {
  set rc [catch {
      sqlite3_prepare $DB {select 5/0} -1 TAIL
  } VM]
  lappend rc $TAIL
} {0 {}}
do_test capi2-3.7 {
  list [sqlite3_step $VM] \
       [sqlite3_column_count $VM] \
       [get_row_values $VM] \
       [get_column_names $VM]
} {SQLITE_ROW 1 {{}} {5/0 NUMERIC}}
do_test capi2-3.8 {
  sqlite3_finalize $VM
} {SQLITE_OK}
do_test capi2-3.9 {
  execsql {CREATE UNIQUE INDEX i1 ON t1(a)}
  set VM [sqlite3_prepare $DB {INSERT INTO t1 VALUES(1,2,3)} -1 TAIL]
  set TAIL
} {}
do_test capi2-3.9b {db changes} {0}
do_test capi2-3.10 {
  list [sqlite3_step $VM] \
       [sqlite3_column_count $VM] \
       [get_row_values $VM] \
       [get_column_names $VM]
} {SQLITE_DONE 0 {} {}}

# Update for v3 - the change has not actually happened until the query is
# finalized. Is this going to cause trouble for anyone? Lee Nelson maybe?
do_test capi2-3.10b {sqlite3_changes $DB} {1}
do_test capi2-3.11 {
  sqlite3_finalize $VM
} {SQLITE_OK}
do_test capi2-3.11b {sqlite3_changes $DB} {1}
do_test capi2-3.12 {
  sqlite3_finalize $VM

} {SQLITE_MISUSE}
do_test capi2-3.13 {
  set VM [sqlite3_prepare $DB {INSERT INTO t1 VALUES(1,3,4)} -1 TAIL]
  list [sqlite3_step $VM] \
       [sqlite3_column_count $VM] \
       [get_row_values $VM] \
       [get_column_names $VM]
} {SQLITE_ERROR 0 {} {}}
do_test capi2-3.13b {db changes} {0}
do_test capi2-3.14 {
  list [sqlite3_finalize $VM] [sqlite3_errmsg $DB]
} {SQLITE_CONSTRAINT {column a is not unique}}
do_test capi2-3.15 {
  set VM [sqlite3_prepare $DB {CREATE TABLE t2(a NOT NULL, b)} -1 TAIL]
  set TAIL
} {}
do_test capi2-3.16 {
  list [sqlite3_step $VM] \
       [sqlite3_column_count $VM] \
       [get_row_values $VM] \
       [get_column_names $VM]
} {SQLITE_DONE 0 {} {}}
do_test capi2-3.17 {
  list [sqlite3_finalize $VM] [sqlite3_errmsg $DB]
} {SQLITE_OK {not an error}}
do_test capi2-3.18 {
  set VM [sqlite3_prepare $DB {INSERT INTO t2 VALUES(NULL,2)} -1 TAIL]
  list [sqlite3_step $VM] \
       [sqlite3_column_count $VM] \
       [get_row_values $VM] \
       [get_column_names $VM]
} {SQLITE_ERROR 0 {} {}}
do_test capi2-3.19 {
  list [sqlite3_finalize $VM] [sqlite3_errmsg $DB]
} {SQLITE_CONSTRAINT {t2.a may not be NULL}}

# Two or more virtual machines exists at the same time.
#
do_test capi2-4.1 {
  set VM1 [sqlite3_prepare $DB {INSERT INTO t2 VALUES(1,2)} -1 TAIL]
  set TAIL
} {}
do_test capi2-4.2 {
  set VM2 [sqlite3_prepare $DB {INSERT INTO t2 VALUES(2,3)} -1 TAIL]
  set TAIL
} {}
do_test capi2-4.3 {
  set VM3 [sqlite3_prepare $DB {INSERT INTO t2 VALUES(3,4)} -1 TAIL]
  set TAIL
} {}
do_test capi2-4.4 {
  list [sqlite3_step $VM2] \
       [sqlite3_column_count $VM2] \
       [get_row_values $VM2] \
       [get_column_names $VM2]
} {SQLITE_DONE 0 {} {}}
do_test capi2-4.5 {
  execsql {SELECT * FROM t2 ORDER BY a}
} {2 3}
do_test capi2-4.6 {
  sqlite3_finalize $VM2
} {SQLITE_OK}
do_test capi2-4.7 {
  list [sqlite3_step $VM3] \
       [sqlite3_column_count $VM3] \
       [get_row_values $VM3] \
       [get_column_names $VM3]
} {SQLITE_DONE 0 {} {}}
do_test capi2-4.8 {
  execsql {SELECT * FROM t2 ORDER BY a}
} {2 3 3 4}
do_test capi2-4.9 {
  sqlite3_finalize $VM3
} {SQLITE_OK}
do_test capi2-4.10 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_DONE 0 {} {}}
do_test capi2-4.11 {
  execsql {SELECT * FROM t2 ORDER BY a}
} {1 2 2 3 3 4}
do_test capi2-4.12 {
  sqlite3_finalize $VM1
} {SQLITE_OK}

# Interleaved SELECTs
#
do_test capi2-5.1 {
  set VM1 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL]
  set VM2 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL]
  set VM3 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL]
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 2 {2 3} {a b {} {}}}
do_test capi2-5.2 {
  list [sqlite3_step $VM2] \
       [sqlite3_column_count $VM2] \
       [get_row_values $VM2] \
       [get_column_names $VM2]
} {SQLITE_ROW 2 {2 3} {a b {} {}}}
do_test capi2-5.3 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 2 {3 4} {a b {} {}}}
do_test capi2-5.4 {
  list [sqlite3_step $VM3] \
       [sqlite3_column_count $VM3] \
       [get_row_values $VM3] \
       [get_column_names $VM3]
} {SQLITE_ROW 2 {2 3} {a b {} {}}}
do_test capi2-5.5 {
  list [sqlite3_step $VM3] \
       [sqlite3_column_count $VM3] \
       [get_row_values $VM3] \
       [get_column_names $VM3]
} {SQLITE_ROW 2 {3 4} {a b {} {}}}
do_test capi2-5.6 {
  list [sqlite3_step $VM3] \
       [sqlite3_column_count $VM3] \
       [get_row_values $VM3] \
       [get_column_names $VM3]
} {SQLITE_ROW 2 {1 2} {a b {} {}}}
do_test capi2-5.7 {
  list [sqlite3_step $VM3] \
       [sqlite3_column_count $VM3] \
       [get_row_values $VM3] \
       [get_column_names $VM3]
} {SQLITE_DONE 2 {} {a b {} {}}}
do_test capi2-5.8 {
  sqlite3_finalize $VM3
} {SQLITE_OK}
do_test capi2-5.9 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 2 {1 2} {a b {} {}}}
do_test capi2-5.10 {
  sqlite3_finalize $VM1
} {SQLITE_OK}
do_test capi2-5.11 {
  list [sqlite3_step $VM2] \
       [sqlite3_column_count $VM2] \
       [get_row_values $VM2] \
       [get_column_names $VM2]
} {SQLITE_ROW 2 {3 4} {a b {} {}}}
do_test capi2-5.12 {
  list [sqlite3_step $VM2] \
       [sqlite3_column_count $VM2] \
       [get_row_values $VM2] \
       [get_column_names $VM2]
} {SQLITE_ROW 2 {1 2} {a b {} {}}}
do_test capi2-5.11 {
  sqlite3_finalize $VM2
} {SQLITE_OK}

# Check for proper SQLITE_BUSY returns.
#
do_test capi2-6.1 {
  execsql {
    BEGIN;
    CREATE TABLE t3(x counter);
    INSERT INTO t3 VALUES(1);
    INSERT INTO t3 VALUES(2);
    INSERT INTO t3 SELECT x+2 FROM t3;
    INSERT INTO t3 SELECT x+4 FROM t3;
    INSERT INTO t3 SELECT x+8 FROM t3;
    COMMIT;
  }
  set VM1 [sqlite3_prepare $DB {SELECT * FROM t3} -1 TAIL]
  sqlite db2 test.db
  execsql {BEGIN} db2
} {}
# Update for v3: BEGIN doesn't write-lock the database. It is quite
# difficult to get v3 to write-lock the database, which causes a few
# problems for test scripts.
#
# do_test capi2-6.2 {
#   list [sqlite3_step $VM1] \
#        [sqlite3_column_count $VM1] \
#        [get_row_values $VM1] \
#        [get_column_names $VM1]
# } {SQLITE_BUSY 0 {} {}}
do_test capi2-6.3 {
  execsql {COMMIT} db2
} {}
do_test capi2-6.4 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 1 1 {x counter}}
do_test capi2-6.5 {
  catchsql {INSERT INTO t3 VALUES(10);} db2
} {1 {database is locked}}
do_test capi2-6.6 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 1 2 {x counter}}
do_test capi2-6.7 {
  execsql {SELECT * FROM t2} db2
} {2 3 3 4 1 2}
do_test capi2-6.8 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 1 3 {x counter}}
do_test capi2-6.9 {
  execsql {SELECT * FROM t2} 
} {2 3 3 4 1 2}
do_test capi2-6.10 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 1 4 {x counter}}
do_test capi2-6.11 {
  execsql {BEGIN}
} {}
do_test capi2-6.12 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 1 5 {x counter}}

do_test capi2-6.13 {
  catchsql {UPDATE t3 SET x=x+1}
} {1 {database table is locked}}
do_test capi2-6.14 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 1 6 {x counter}}

do_test capi2-6.15 {
  execsql {SELECT * FROM t1}
} {1 2 3}
do_test capi2-6.16 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 1 7 {x counter}}
do_test capi2-6.17 {
  catchsql {UPDATE t1 SET b=b+1}
} {0 {}}
do_test capi2-6.18 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 1 8 {x counter}}
do_test capi2-6.19 {
  execsql {SELECT * FROM t1}
} {1 3 3}
do_test capi2-6.20 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 1 9 {x counter}}
do_test capi2-6.21 {
  execsql {ROLLBACK; SELECT * FROM t1}
} {1 2 3}
do_test capi2-6.22 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 1 10 {x counter}}
do_test capi2-6.23 {
  execsql {BEGIN TRANSACTION;}
} {}
do_test capi2-6.24 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 1 11 {x counter}}
do_test capi2-6.25 {
  execsql {
    INSERT INTO t1 VALUES(2,3,4);
    SELECT * FROM t1;
  }
} {1 2 3 2 3 4}
do_test capi2-6.26 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 1 12 {x counter}}
do_test capi2-6.27 {
  catchsql {
    INSERT INTO t1 VALUES(2,4,5);
    SELECT * FROM t1;
  }
} {1 {column a is not unique}}
do_test capi2-6.28 {
  list [sqlite3_step $VM1] \
       [sqlite3_column_count $VM1] \
       [get_row_values $VM1] \
       [get_column_names $VM1]
} {SQLITE_ROW 1 13 {x counter}}
do_test capi2-6.99 {
  sqlite3_finalize $VM1
} {SQLITE_OK}
catchsql {ROLLBACK}

do_test capi2-7.1 {
  stepsql $DB {
    SELECT * FROM t1
  }
} {0 1 2 3}
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
  }
} {0 1}
do_test capi2-7.4 {
  stepsql $DB {
    INSERT INTO t1 SELECT a+1,b+1,c+1 FROM t1;
  }
} {0 1}
do_test capi2-7.4b {db changes} {1}
do_test capi2-7.5 {
  stepsql $DB {
    UPDATE t1 SET a=a+10;
  }
} {0 2}
do_test capi2-7.5b {db changes} {2}
do_test capi2-7.6 {
  stepsql $DB {
    SELECT * FROM t1;
  }
} {0 21 2 3 22 3 4}
do_test capi2-7.7 {
  stepsql $DB {
    INSERT INTO t1 SELECT a+2,b+2,c+2 FROM t1;
  }
} {0 2}
do_test capi2-7.8 {
  db changes
} {2}
do_test capi2-7.9 {
  stepsql $DB {
    SELECT * FROM t1;
  }
} {0 21 2 3 22 3 4 23 4 5 24 5 6}
do_test capi2-7.10 {
  stepsql $DB {
    UPDATE t1 SET a=a-20;
    SELECT * FROM t1;
  }
} {0 4 1 2 3 2 3 4 3 4 5 4 5 6}
do_test capi2-7.11 {
  db changes
} {0}
do_test capi2-7.12 {
  set x [stepsql $DB {EXPLAIN SELECT * FROM t1}]
  lindex $x 0
} {0}

# Ticket #261 - make sure we can finalize before the end of a query.
#
do_test capi2-8.1 {
  set VM1 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL]
  sqlite3_finalize $VM1
} {}
  
# Tickets #384 and #385 - make sure the TAIL argument to sqlite3_prepare
# and all of the return pointers in sqlite_step can be null.
#
do_test capi2-9.1 {
  set VM1 [sqlite3_prepare $DB {SELECT * FROM t2} -1 DUMMY]
  sqlite_step $VM1
  sqlite3_finalize $VM1
} {}

db2 close

finish_test







|





|











|













|











|






|

|




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
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
  }
} {0 1}
do_test capi2-7.4 {
  stepsql $DB {
    INSERT INTO t1 SELECT a+1,b+1,c+1 FROM t1;
  }
} {0 1}
do_test capi2-7.4b {sqlite3_changes $DB} {1}
do_test capi2-7.5 {
  stepsql $DB {
    UPDATE t1 SET a=a+10;
  }
} {0 2}
do_test capi2-7.5b {sqlite3_changes $DB} {2}
do_test capi2-7.6 {
  stepsql $DB {
    SELECT * FROM t1;
  }
} {0 21 2 3 22 3 4}
do_test capi2-7.7 {
  stepsql $DB {
    INSERT INTO t1 SELECT a+2,b+2,c+2 FROM t1;
  }
} {0 2}
do_test capi2-7.8 {
  sqlite3_changes $DB
} {2}
do_test capi2-7.9 {
  stepsql $DB {
    SELECT * FROM t1;
  }
} {0 21 2 3 22 3 4 23 4 5 24 5 6}
do_test capi2-7.10 {
  stepsql $DB {
    UPDATE t1 SET a=a-20;
    SELECT * FROM t1;
  }
} {0 4 1 2 3 2 3 4 3 4 5 4 5 6}
do_test capi2-7.11 {
  sqlite3_changes $DB
} {0}
do_test capi2-7.12 {
  set x [stepsql $DB {EXPLAIN SELECT * FROM t1}]
  lindex $x 0
} {0}

# Ticket #261 - make sure we can finalize before the end of a query.
#
do_test capi2-8.1 {
  set VM1 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL]
  sqlite3_finalize $VM1
} {SQLITE_OK}
  
# Tickets #384 and #385 - make sure the TAIL argument to sqlite3_prepare
# and all of the return pointers in sqlite_step can be null.
#
do_test capi2-9.1 {
  set VM1 [sqlite3_prepare $DB {SELECT * FROM t2} -1 DUMMY]
  sqlite3_step $VM1
  sqlite3_finalize $VM1
} {SQLITE_OK}

db2 close

finish_test
Changes to test/quick.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 runs all tests.
#
# $Id: quick.test,v 1.21 2004/06/14 23:46:48 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {}
set ISQUICK 1













|







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 runs all tests.
#
# $Id: quick.test,v 1.22 2004/06/15 02:44:20 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {}
set ISQUICK 1

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  format3.test
}

lappend EXCLUDE ioerr.test        ;# seg-faults (?)
lappend EXCLUDE memdb.test        ;# fails - malformed database
lappend EXCLUDE version.test      ;# This is obsolete.

# Some tests fail in these file as a result of the partial manifest types
# implementation.
lappend EXCLUDE capi2.test 

if {[sqlite -has-codec]} {
  lappend EXCLUDE \
    attach.test \
    attach2.test \
    auth.test \
    format3.test \
    version.test







<
<
<
<







28
29
30
31
32
33
34




35
36
37
38
39
40
41
  format3.test
}

lappend EXCLUDE ioerr.test        ;# seg-faults (?)
lappend EXCLUDE memdb.test        ;# fails - malformed database
lappend EXCLUDE version.test      ;# This is obsolete.





if {[sqlite -has-codec]} {
  lappend EXCLUDE \
    attach.test \
    attach2.test \
    auth.test \
    format3.test \
    version.test
Changes to test/tester.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 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 some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.35 2004/05/21 10:08:55 danielk1977 Exp $

# Make sure tclsqlite was compiled correctly.  Abort now with an
# error message if not.
#
if {[sqlite -tcl-uses-utf]} {
  if {"\u1234"=="u1234"} {
    puts stderr "***** BUILD PROBLEM *****"













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 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 some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.36 2004/06/15 02:44:20 danielk1977 Exp $

# Make sure tclsqlite was compiled correctly.  Abort now with an
# error message if not.
#
if {[sqlite -tcl-uses-utf]} {
  if {"\u1234"=="u1234"} {
    puts stderr "***** BUILD PROBLEM *****"
198
199
200
201
202
203
204
205
206





207
208
209
210
211
212
213
  set sql [string trim $sql]
  set r 0
  while {[string length $sql]>0} {
    if {[catch {sqlite3_prepare $dbptr $sql -1 sqltail} vm]} {
      return [list 1 $vm]
    }
    set sql [string trim $sqltail]
    while {[sqlite_step $vm N VAL COL]=="SQLITE_ROW"} {
      foreach v $VAL {lappend r $v}





    }
    if {[catch {sqlite3_finalize $vm} errmsg]} {
      return [list 1 $errmsg]
    }
  }
  return $r
}







|
|
>
>
>
>
>







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
  set sql [string trim $sql]
  set r 0
  while {[string length $sql]>0} {
    if {[catch {sqlite3_prepare $dbptr $sql -1 sqltail} vm]} {
      return [list 1 $vm]
    }
    set sql [string trim $sqltail]
#    while {[sqlite_step $vm N VAL COL]=="SQLITE_ROW"} {
#      foreach v $VAL {lappend r $v}
#    }
    while {[sqlite3_step $vm]=="SQLITE_ROW"} {
      for {set i 0} {$i<[sqlite3_data_count $vm]} {incr i} {
        lappend r [sqlite3_column_text $vm $i]
      }
    }
    if {[catch {sqlite3_finalize $vm} errmsg]} {
      return [list 1 $errmsg]
    }
  }
  return $r
}