SQLite

Check-in [157db33e09]
Login

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

Overview
Comment:Fix error reporting path for errors that occur while reading the database schema. (CVS 1757)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 157db33e09399f31bcdaf58ea90fe618fefcd9bd
User & Date: danielk1977 2004-06-29 08:59:35.000
Context
2004-06-29
10:53
Do not set new error messages after a malloc failure. (CVS 1758) (check-in: f46251ee0a user: drh tags: trunk)
08:59
Fix error reporting path for errors that occur while reading the database schema. (CVS 1757) (check-in: 157db33e09 user: danielk1977 tags: trunk)
07:45
Bug-fixes to get the two threadtest C programs working again. (CVS 1756) (check-in: ffd3312b66 user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/attach.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2003 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.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.19 2004/06/28 01:11:46 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called by the parser to process an ATTACH statement:
**
**     ATTACH DATABASE filename AS dbname













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2003 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.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.20 2004/06/29 08:59:35 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called by the parser to process an ATTACH statement:
**
**     ATTACH DATABASE filename AS dbname
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
    sqliteCodecAttach(db, db->nDb-1, zKey, nKey);
  }
#endif
  sqliteFree(zFile);
  db->flags &= ~SQLITE_Initialized;
  if( pParse->nErr ) return;
  if( rc==SQLITE_OK ){
    rc = sqlite3ReadSchema(pParse->db, &pParse->zErrMsg);
  }
  if( rc ){
    int i = db->nDb - 1;
    assert( i>=2 );
    if( db->aDb[i].pBt ){
      sqlite3BtreeClose(db->aDb[i].pBt);
      db->aDb[i].pBt = 0;
    }
    sqlite3ResetInternalSchema(db, 0);

    pParse->nErr++;
    pParse->rc = SQLITE_ERROR;

  }
}

/*
** This routine is called by the parser to process a DETACH statement:
**
**    DETACH DATABASE dbname







|









>
|
|
>







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
    sqliteCodecAttach(db, db->nDb-1, zKey, nKey);
  }
#endif
  sqliteFree(zFile);
  db->flags &= ~SQLITE_Initialized;
  if( pParse->nErr ) return;
  if( rc==SQLITE_OK ){
    rc = sqlite3ReadSchema(pParse);
  }
  if( rc ){
    int i = db->nDb - 1;
    assert( i>=2 );
    if( db->aDb[i].pBt ){
      sqlite3BtreeClose(db->aDb[i].pBt);
      db->aDb[i].pBt = 0;
    }
    sqlite3ResetInternalSchema(db, 0);
    if( 0==pParse->nErr ){
      pParse->nErr++;
      pParse->rc = SQLITE_ERROR;
    }
  }
}

/*
** This routine is called by the parser to process a DETACH statement:
**
**    DETACH DATABASE dbname
Changes to src/build.c.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.236 2004/06/29 07:45:33 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.237 2004/06/29 08:59:35 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
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
  pParse->nSet = 0;
  pParse->nAgg = 0;
  pParse->nVar = 0;
  pParse->cookieMask = 0;
}

/*
** Locate the in-memory structure that describes 
** a particular database table given the name
** of that table and (optionally) the name of the database
** containing the table.  Return NULL if not found.
**
** If zDatabase is 0, all databases are searched for the
** table and the first matching table is returned.  (No checking
** for duplicate table names is done.)  The search order is
** TEMP first, then MAIN, then any auxiliary databases added
** using the ATTACH command.
**
** See also sqlite3LocateTable().
*/
Table *sqlite3FindTable(sqlite *db, const char *zName, const char *zDatabase){
  Table *p = 0;
  int i;
  int rc = sqlite3ReadSchema(db, 0);
  assert( zName!=0 );

  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
    if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
    p = sqlite3HashFind(&db->aDb[j].tblHash, zName, strlen(zName)+1);
    if( p ) break;
  }
  return p;
}

/*
** Locate the in-memory structure that describes 
** a particular database table given the name
** of that table and (optionally) the name of the database
** containing the table.  Return NULL if not found.
** Also leave an error message in pParse->zErrMsg.
**
** The difference between this routine and sqlite3FindTable()
** is that this routine leaves an error message in pParse->zErrMsg
** where sqlite3FindTable() does not.
*/
Table *sqlite3LocateTable(Parse *pParse, const char *zName, const char *zDbase){
  Table *p;







  p = sqlite3FindTable(pParse->db, zName, zDbase);
  if( p==0 ){
    if( !(pParse->db->flags & SQLITE_Initialized) ){
      /* If the schema is not initialised at this point, it must be because
      ** the database is locked. */
      pParse->nErr++;
      pParse->rc = SQLITE_BUSY;
    }else if( zDbase ){
      sqlite3ErrorMsg(pParse, "no such table: %s.%s", zDbase, zName);
    }else if( sqlite3FindTable(pParse->db, zName, 0)!=0 ){
      sqlite3ErrorMsg(pParse, "table \"%s\" is not in database \"%s\"",
         zName, zDbase);
    }else{
      sqlite3ErrorMsg(pParse, "no such table: %s", zName);
    }







|
<
|
|

|
|
|
<
|






<

>
|









|
<
|
|
|

|
|
|



>
>
>
>
>
>



<
<
<
<
<
|







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
  pParse->nSet = 0;
  pParse->nAgg = 0;
  pParse->nVar = 0;
  pParse->cookieMask = 0;
}

/*
** Locate the in-memory structure that describes a particular database

** table given the name of that table and (optionally) the name of the
** database containing the table.  Return NULL if not found.
**
** If zDatabase is 0, all databases are searched for the table and the
** first matching table is returned.  (No checking for duplicate table
** names is done.)  The search order is TEMP first, then MAIN, then any

** auxiliary databases added using the ATTACH command.
**
** See also sqlite3LocateTable().
*/
Table *sqlite3FindTable(sqlite *db, const char *zName, const char *zDatabase){
  Table *p = 0;
  int i;

  assert( zName!=0 );
  assert( (db->flags & SQLITE_Initialized) || db->init.busy );
  for(i=0; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
    if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
    p = sqlite3HashFind(&db->aDb[j].tblHash, zName, strlen(zName)+1);
    if( p ) break;
  }
  return p;
}

/*
** Locate the in-memory structure that describes a particular database

** table given the name of that table and (optionally) the name of the
** database containing the table.  Return NULL if not found.  Also leave an
** error message in pParse->zErrMsg.
**
** The difference between this routine and sqlite3FindTable() is that this
** routine leaves an error message in pParse->zErrMsg where
** sqlite3FindTable() does not.
*/
Table *sqlite3LocateTable(Parse *pParse, const char *zName, const char *zDbase){
  Table *p;

  /* Read the database schema. If an error occurs, leave an error message
  ** and code in pParse and return NULL. */
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    return 0;
  }

  p = sqlite3FindTable(pParse->db, zName, zDbase);
  if( p==0 ){





    if( zDbase ){
      sqlite3ErrorMsg(pParse, "no such table: %s.%s", zDbase, zName);
    }else if( sqlite3FindTable(pParse->db, zName, 0)!=0 ){
      sqlite3ErrorMsg(pParse, "table \"%s\" is not in database \"%s\"",
         zName, zDbase);
    }else{
      sqlite3ErrorMsg(pParse, "no such table: %s", zName);
    }
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
** for duplicate index names is done.)  The search order is
** TEMP first, then MAIN, then any auxiliary databases added
** using the ATTACH command.
*/
Index *sqlite3FindIndex(sqlite *db, const char *zName, const char *zDb){
  Index *p = 0;
  int i;
  int rc = sqlite3ReadSchema(db, 0);
  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
    p = sqlite3HashFind(&db->aDb[j].idxHash, zName, strlen(zName)+1);
    if( p ) break;
  }
  return p;
}







|
|







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
** for duplicate index names is done.)  The search order is
** TEMP first, then MAIN, then any auxiliary databases added
** using the ATTACH command.
*/
Index *sqlite3FindIndex(sqlite *db, const char *zName, const char *zDb){
  Index *p = 0;
  int i;
  assert( (db->flags & SQLITE_Initialized) || db->init.busy );
  for(i=0; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
    p = sqlite3HashFind(&db->aDb[j].idxHash, zName, strlen(zName)+1);
    if( p ) break;
  }
  return p;
}
638
639
640
641
642
643
644

645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
    }
  }

  /* Make sure the new table name does not collide with an existing
  ** index or table name in the same database.  Issue an error message if
  ** it does.
  */

  pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName);
  if( pTable ){
    sqlite3ErrorMsg(pParse, "table %T already exists", pName);
    sqliteFree(zName);
    return;
  }
  if( (pIdx = sqlite3FindIndex(db, zName, 0))!=0 &&
          (pIdx->iDb==0 || !db->init.busy) ){
    sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
    sqliteFree(zName);
    return;
  }
  pTable = sqliteMalloc( sizeof(Table) );
  if( pTable==0 ){
    pParse->rc = SQLITE_NOMEM;







>






|
|







636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
    }
  }

  /* Make sure the new table name does not collide with an existing
  ** index or table name in the same database.  Issue an error message if
  ** it does.
  */
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) return;
  pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName);
  if( pTable ){
    sqlite3ErrorMsg(pParse, "table %T already exists", pName);
    sqliteFree(zName);
    return;
  }
  if( (pIdx = sqlite3FindIndex(db, zName, 0))!=0 && 
      ( iDb==0 || !db->init.busy) ){
    sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
    sqliteFree(zName);
    return;
  }
  pTable = sqliteMalloc( sizeof(Table) );
  if( pTable==0 ){
    pParse->rc = SQLITE_NOMEM;
1573
1574
1575
1576
1577
1578
1579

1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596

1597
1598
1599
1600
1601
1602
1603
    if( pTab->pSelect ){
      sqliteViewResetColumnNames(pTab);
    }
  }
  DbClearProperty(db, idx, DB_UnresetViews);
}


/*
** Given a token, look up a table with that name.  If not found, leave
** an error for the parser to find and return NULL.
*/
Table *sqlite3TableFromToken(Parse *pParse, Token *pTok){
  char *zName;
  Table *pTab;
  zName = sqlite3NameFromToken(pTok);
  if( zName==0 ) return 0;
  pTab = sqlite3FindTable(pParse->db, zName, 0);
  sqliteFree(zName);
  if( pTab==0 ){
    sqlite3ErrorMsg(pParse, "no such table: %T", pTok);
    pParse->checkSchema = 1;
  }
  return pTab;
}


/*
** This routine is called to do the work of a DROP TABLE statement.
** pName is the name of the table to be dropped.
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
  Table *pTab;







>

















>







1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
    if( pTab->pSelect ){
      sqliteViewResetColumnNames(pTab);
    }
  }
  DbClearProperty(db, idx, DB_UnresetViews);
}

#if 0
/*
** Given a token, look up a table with that name.  If not found, leave
** an error for the parser to find and return NULL.
*/
Table *sqlite3TableFromToken(Parse *pParse, Token *pTok){
  char *zName;
  Table *pTab;
  zName = sqlite3NameFromToken(pTok);
  if( zName==0 ) return 0;
  pTab = sqlite3FindTable(pParse->db, zName, 0);
  sqliteFree(zName);
  if( pTab==0 ){
    sqlite3ErrorMsg(pParse, "no such table: %T", pTok);
    pParse->checkSchema = 1;
  }
  return pTab;
}
#endif

/*
** This routine is called to do the work of a DROP TABLE statement.
** pName is the name of the table to be dropped.
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
  Table *pTab;
1954
1955
1956
1957
1958
1959
1960

1961
1962
1963
1964
1965
1966
1967

1968
1969
1970
1971
1972
1973
1974
  **
  ** If pName==0 it means that we are
  ** dealing with a primary key or UNIQUE constraint.  We have to invent our
  ** own name.
  */
  if( pName ){
    zName = sqlite3NameFromToken(pName);

    if( zName==0 ) goto exit_create_index;
    if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
      goto exit_create_index;
    }
    if( !db->init.busy ){
      Index *pISameName;    /* Another index with the same name */
      Table *pTSameName;    /* A table with same name as the index */

      if( (pISameName = sqlite3FindIndex(db, zName, db->aDb[iDb].zName))!=0 ){
        sqlite3ErrorMsg(pParse, "index %s already exists", zName);
        goto exit_create_index;
      }
      if( (pTSameName = sqlite3FindTable(db, zName, 0))!=0 ){
        sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
        goto exit_create_index;







>







>







1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
  **
  ** If pName==0 it means that we are
  ** dealing with a primary key or UNIQUE constraint.  We have to invent our
  ** own name.
  */
  if( pName ){
    zName = sqlite3NameFromToken(pName);
    if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
    if( zName==0 ) goto exit_create_index;
    if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
      goto exit_create_index;
    }
    if( !db->init.busy ){
      Index *pISameName;    /* Another index with the same name */
      Table *pTSameName;    /* A table with same name as the index */
      if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
      if( (pISameName = sqlite3FindIndex(db, zName, db->aDb[iDb].zName))!=0 ){
        sqlite3ErrorMsg(pParse, "index %s already exists", zName);
        goto exit_create_index;
      }
      if( (pTSameName = sqlite3FindTable(db, zName, 0))!=0 ){
        sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
        goto exit_create_index;
2238
2239
2240
2241
2242
2243
2244

2245
2246
2247
2248
2249
2250
2251
void sqlite3DropIndex(Parse *pParse, SrcList *pName){
  Index *pIndex;
  Vdbe *v;
  sqlite *db = pParse->db;

  if( pParse->nErr || sqlite3_malloc_failed ) return;
  assert( pName->nSrc==1 );

  pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
  if( pIndex==0 ){
    sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
    pParse->checkSchema = 1;
    goto exit_drop_index;
  }
  if( pIndex->autoIndex ){







>







2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
void sqlite3DropIndex(Parse *pParse, SrcList *pName){
  Index *pIndex;
  Vdbe *v;
  sqlite *db = pParse->db;

  if( pParse->nErr || sqlite3_malloc_failed ) return;
  assert( pName->nSrc==1 );
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) return;
  pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
  if( pIndex==0 ){
    sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
    pParse->checkSchema = 1;
    goto exit_drop_index;
  }
  if( pIndex->autoIndex ){
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.238 2004/06/29 07:45:34 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.239 2004/06/29 08:59:35 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387




388
389
390
391
392
393
394
  return rc;
}

/*
** This routine is a no-op if the database schema is already initialised.
** Otherwise, the schema is loaded. An error code is returned.
*/
int sqlite3ReadSchema(sqlite *db, char **pzErrMsg){
  int rc = SQLITE_OK;

  if( !db->init.busy ){
    if( (db->flags & SQLITE_Initialized)==0 ){
      rc = sqlite3Init(db, pzErrMsg);
    }
  }
  assert( rc!=SQLITE_OK || (db->flags & SQLITE_Initialized)||db->init.busy );




  return rc;
}

/*
** The version of the library
*/
const char rcsid3[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $";







|

|


|



>
>
>
>







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
  return rc;
}

/*
** This routine is a no-op if the database schema is already initialised.
** Otherwise, the schema is loaded. An error code is returned.
*/
int sqlite3ReadSchema(Parse *pParse){
  int rc = SQLITE_OK;
  sqlite3 *db = pParse->db;
  if( !db->init.busy ){
    if( (db->flags & SQLITE_Initialized)==0 ){
      rc = sqlite3Init(db, &pParse->zErrMsg);
    }
  }
  assert( rc!=SQLITE_OK || (db->flags & SQLITE_Initialized)||db->init.busy );
  if( rc!=SQLITE_OK ){
    pParse->rc = rc;
    pParse->nErr++;
  }
  return rc;
}

/*
** The version of the library
*/
const char rcsid3[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $";
Changes to src/pragma.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2003 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.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.55 2004/06/29 07:45:34 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
# include "pager.h"
# include "btree.h"













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2003 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.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.56 2004/06/29 08:59:35 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
# include "pager.h"
# include "btree.h"
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
      }
      return 1;
    }
  }
  return 0;
}

/*
** Check to make sure the schema is loaded.  Return 1 if it is not.
*/
static int checkSchema(Parse *pParse){
  int rc = sqlite3ReadSchema(pParse->db, &pParse->zErrMsg);
  if( SQLITE_OK!=rc ){
    pParse->nErr++;
    pParse->rc = rc;
    return 1;
  }
  return 0;
}

/*
** Process a pragma statement.  
**
** Pragmas are of this form:
**
**      PRAGMA [database.]id [= value]
**







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







111
112
113
114
115
116
117













118
119
120
121
122
123
124
      }
      return 1;
    }
  }
  return 0;
}














/*
** Process a pragma statement.  
**
** Pragmas are of this form:
**
**      PRAGMA [database.]id [= value]
**
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
      { OP_Dup,         0, 0,        0},
      { OP_Integer,     0, 0,        0},
      { OP_Ne,          0, 6,        0},
      { OP_Integer,     0, 0,        0},  /* 5 */
      { OP_Callback,    1, 0,        0},
    };
    int addr;
    if( checkSchema(pParse) ) goto pragma_out;
    if( !zRight ){
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
      addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
      sqlite3VdbeChangeP1(v, addr, iDb);
      sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
    }else{







|







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
      { OP_Dup,         0, 0,        0},
      { OP_Integer,     0, 0,        0},
      { OP_Ne,          0, 6,        0},
      { OP_Integer,     0, 0,        0},  /* 5 */
      { OP_Callback,    1, 0,        0},
    };
    int addr;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    if( !zRight ){
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
      addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
      sqlite3VdbeChangeP1(v, addr, iDb);
      sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
    }else{
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
  ** to its default value when the database is closed and reopened.
  ** N should be a positive integer.
  */
  if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
    static VdbeOpList getCacheSize[] = {
      { OP_Callback,    1, 0,        0},
    };
    if( checkSchema(pParse) ) goto pragma_out;
    if( !zRight ){
      int size = db->aDb[iDb].cache_size;
      assert( size>0 );
      sqlite3VdbeAddOp(v, OP_Integer, size, 0);
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
      sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);







|







224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
  ** to its default value when the database is closed and reopened.
  ** N should be a positive integer.
  */
  if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
    static VdbeOpList getCacheSize[] = {
      { OP_Callback,    1, 0,        0},
    };
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    if( !zRight ){
      int size = db->aDb[iDb].cache_size;
      assert( size>0 );
      sqlite3VdbeAddOp(v, OP_Integer, size, 0);
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
      sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  ** default value will be restored the next time the database is
  ** opened.
  */
  if( sqlite3StrICmp(zLeft,"synchronous")==0 ){
    static VdbeOpList getSync[] = {
      { OP_Callback,    1, 0,        0},
    };
    if( checkSchema(pParse) ) goto pragma_out;
    if( !zRight ){
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].safety_level-1, 0);
      sqlite3VdbeAddOpList(v, ArraySize(getSync), getSync);
    }else{
      if( !db->autoCommit ){







|







253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
  ** default value will be restored the next time the database is
  ** opened.
  */
  if( sqlite3StrICmp(zLeft,"synchronous")==0 ){
    static VdbeOpList getSync[] = {
      { OP_Callback,    1, 0,        0},
    };
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    if( !zRight ){
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].safety_level-1, 0);
      sqlite3VdbeAddOpList(v, ArraySize(getSync), getSync);
    }else{
      if( !db->autoCommit ){
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
  ** name:       Column name
  ** type:       Column declaration type.
  ** notnull:    True if 'NOT NULL' is part of column declaration
  ** dflt_value: The default value for the column, if any.
  */
  if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
    Table *pTab;
    if( checkSchema(pParse) ) goto pragma_out;
    pTab = sqlite3FindTable(db, zRight, 0);
    if( pTab ){
      int i;
      sqlite3VdbeSetNumCols(v, 6);
      sqlite3VdbeSetColName(v, 0, "cid", P3_STATIC);
      sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
      sqlite3VdbeSetColName(v, 2, "type", P3_STATIC);







|







298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
  ** name:       Column name
  ** type:       Column declaration type.
  ** notnull:    True if 'NOT NULL' is part of column declaration
  ** dflt_value: The default value for the column, if any.
  */
  if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
    Table *pTab;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    pTab = sqlite3FindTable(db, zRight, 0);
    if( pTab ){
      int i;
      sqlite3VdbeSetNumCols(v, 6);
      sqlite3VdbeSetColName(v, 0, "cid", P3_STATIC);
      sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
      sqlite3VdbeSetColName(v, 2, "type", P3_STATIC);
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
      }
    }
  }else

  if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){
    Index *pIdx;
    Table *pTab;
    if( checkSchema(pParse) ) goto pragma_out;
    pIdx = sqlite3FindIndex(db, zRight, 0);
    if( pIdx ){
      int i;
      pTab = pIdx->pTable;
      sqlite3VdbeSetNumCols(v, 3);
      sqlite3VdbeSetColName(v, 0, "seqno", P3_STATIC);
      sqlite3VdbeSetColName(v, 1, "cid", P3_STATIC);







|







327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
      }
    }
  }else

  if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){
    Index *pIdx;
    Table *pTab;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    pIdx = sqlite3FindIndex(db, zRight, 0);
    if( pIdx ){
      int i;
      pTab = pIdx->pTable;
      sqlite3VdbeSetNumCols(v, 3);
      sqlite3VdbeSetColName(v, 0, "seqno", P3_STATIC);
      sqlite3VdbeSetColName(v, 1, "cid", P3_STATIC);
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
      }
    }
  }else

  if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){
    Index *pIdx;
    Table *pTab;
    if( checkSchema(pParse) ) goto pragma_out;
    pTab = sqlite3FindTable(db, zRight, 0);
    if( pTab ){
      v = sqlite3GetVdbe(pParse);
      pIdx = pTab->pIndex;
      if( pIdx ){
        int i = 0; 
        sqlite3VdbeSetNumCols(v, 3);







|







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
      }
    }
  }else

  if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){
    Index *pIdx;
    Table *pTab;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    pTab = sqlite3FindTable(db, zRight, 0);
    if( pTab ){
      v = sqlite3GetVdbe(pParse);
      pIdx = pTab->pIndex;
      if( pIdx ){
        int i = 0; 
        sqlite3VdbeSetNumCols(v, 3);
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
      }
    }
  }else

  if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){
    FKey *pFK;
    Table *pTab;
    if( checkSchema(pParse) ) goto pragma_out;
    pTab = sqlite3FindTable(db, zRight, 0);
    if( pTab ){
      v = sqlite3GetVdbe(pParse);
      pFK = pTab->pFKey;
      if( pFK ){
        int i = 0; 
        sqlite3VdbeSetNumCols(v, 5);







|







376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
      }
    }
  }else

  if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){
    FKey *pFK;
    Table *pTab;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    pTab = sqlite3FindTable(db, zRight, 0);
    if( pTab ){
      v = sqlite3GetVdbe(pParse);
      pFK = pTab->pFKey;
      if( pFK ){
        int i = 0; 
        sqlite3VdbeSetNumCols(v, 5);
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
        }
      }
    }
  }else

  if( sqlite3StrICmp(zLeft, "database_list")==0 ){
    int i;
    if( checkSchema(pParse) ) goto pragma_out;
    sqlite3VdbeSetNumCols(v, 3);
    sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
    sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
    sqlite3VdbeSetColName(v, 2, "file", P3_STATIC);
    for(i=0; i<db->nDb; i++){
      if( db->aDb[i].pBt==0 ) continue;
      assert( db->aDb[i].zName!=0 );







|







409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
        }
      }
    }
  }else

  if( sqlite3StrICmp(zLeft, "database_list")==0 ){
    int i;
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    sqlite3VdbeSetNumCols(v, 3);
    sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
    sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
    sqlite3VdbeSetColName(v, 2, "file", P3_STATIC);
    for(i=0; i<db->nDb; i++){
      if( db->aDb[i].pBt==0 ) continue;
      assert( db->aDb[i].zName!=0 );
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
      { OP_Integer,     0, 0,        0},
      { OP_Ne,          0, 0,        0},    /* 2 */
      { OP_String8,      0, 0,        "ok"},
      { OP_Callback,    1, 0,        0},
    };

    /* Initialize the VDBE program */
    if( checkSchema(pParse) ) goto pragma_out;
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);
    sqlite3VdbeAddOpList(v, ArraySize(initCode), initCode);

    /* Do an integrity check on each database file */
    for(i=0; i<db->nDb; i++){
      HashElem *x;







|







460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
      { OP_Integer,     0, 0,        0},
      { OP_Ne,          0, 0,        0},    /* 2 */
      { OP_String8,      0, 0,        "ok"},
      { OP_Callback,    1, 0,        0},
    };

    /* Initialize the VDBE program */
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);
    sqlite3VdbeAddOpList(v, ArraySize(initCode), initCode);

    /* Do an integrity check on each database file */
    for(i=0; i<db->nDb; i++){
      HashElem *x;
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
      { "UTF-16",   0 /* Filled in at run-time */ },
      { "UTF16",    0 /* Filled in at run-time */ },
      { 0, 0 }
    };
    struct EncName *pEnc;
    encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE;
    if( !zRight ){    /* "PRAGMA encoding" */
      if( checkSchema(pParse) ) goto pragma_out;
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
        if( pEnc->enc==pParse->db->enc ){
          sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC);
          break;







|







608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
      { "UTF-16",   0 /* Filled in at run-time */ },
      { "UTF16",    0 /* Filled in at run-time */ },
      { 0, 0 }
    };
    struct EncName *pEnc;
    encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE;
    if( !zRight ){    /* "PRAGMA encoding" */
      if( sqlite3ReadSchema(pParse) ) goto pragma_out;
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
        if( pEnc->enc==pParse->db->enc ){
          sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC);
          break;
Changes to src/sqliteInt.h.
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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.302 2004/06/28 13:09:11 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

#include "config.h"
#include "sqlite3.h"
#include "hash.h"













|







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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.303 2004/06/29 08:59:35 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

#include "config.h"
#include "sqlite3.h"
#include "hash.h"
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
char sqlite3ExprAffinity(Expr *pExpr);
int sqlite3atoi64(const char*, i64*);
void sqlite3Error(sqlite *, int, const char*,...);
void *sqlite3HexToBlob(const char *z);
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
const char *sqlite3ErrStr(int);
int sqlite3ReadUniChar(const char *zStr, int *pOffset, u8 *pEnc, int fold);
int sqlite3ReadSchema(sqlite *db, char **);
CollSeq *sqlite3FindCollSeq(sqlite *,u8 enc, const char *,int,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3CheckIndexCollSeq(Parse *, Index *);
int sqlite3CheckObjectName(Parse *, const char *);
void sqlite3VdbeSetChanges(sqlite3 *, int);







|







1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
char sqlite3ExprAffinity(Expr *pExpr);
int sqlite3atoi64(const char*, i64*);
void sqlite3Error(sqlite *, int, const char*,...);
void *sqlite3HexToBlob(const char *z);
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
const char *sqlite3ErrStr(int);
int sqlite3ReadUniChar(const char *zStr, int *pOffset, u8 *pEnc, int fold);
int sqlite3ReadSchema(Parse *pParse);
CollSeq *sqlite3FindCollSeq(sqlite *,u8 enc, const char *,int,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3CheckIndexCollSeq(Parse *, Index *);
int sqlite3CheckObjectName(Parse *, const char *);
void sqlite3VdbeSetChanges(sqlite3 *, int);
Changes to src/trigger.c.
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
  sqlite3ExprDelete(pTrigger->pWhen);
  sqlite3IdListDelete(pTrigger->pColumns);
  if( pTrigger->nameToken.dyn ) sqliteFree((char*)pTrigger->nameToken.z);
  sqliteFree(pTrigger);
}

/*
 * This function is called to drop a trigger from the database schema. 
 *
 * This may be called directly from the parser and therefore identifies
 * the trigger by name.  The sqlite3DropTriggerPtr() routine does the
 * same job as this routine except it take a spointer to the trigger
 * instead of the trigger name.
 *
 * Note that this function does not delete the trigger entirely. Instead it
 * removes it from the internal schema and places it in the trigDrop hash 
 * table. This is so that the trigger can be restored into the database schema
 * if the transaction is rolled back.
 */
void sqlite3DropTrigger(Parse *pParse, SrcList *pName){
  Trigger *pTrigger = 0;
  int i;
  const char *zDb;
  const char *zName;
  int nName;
  sqlite *db = pParse->db;

  if( sqlite3_malloc_failed ) goto drop_trigger_cleanup;
  if( SQLITE_OK!=sqlite3ReadSchema(db, &pParse->zErrMsg) ){
    pParse->nErr++;
    goto drop_trigger_cleanup;
  }

  assert( pName->nSrc==1 );
  zDb = pName->a[0].zDatabase;
  zName = pName->a[0].zName;
  nName = strlen(zName);







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









|
<







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
  sqlite3ExprDelete(pTrigger->pWhen);
  sqlite3IdListDelete(pTrigger->pColumns);
  if( pTrigger->nameToken.dyn ) sqliteFree((char*)pTrigger->nameToken.z);
  sqliteFree(pTrigger);
}

/*
** This function is called to drop a trigger from the database schema. 
**
** This may be called directly from the parser and therefore identifies
** the trigger by name.  The sqlite3DropTriggerPtr() routine does the
** same job as this routine except it takes a pointer to the trigger
** instead of the trigger name.
**/





void sqlite3DropTrigger(Parse *pParse, SrcList *pName){
  Trigger *pTrigger = 0;
  int i;
  const char *zDb;
  const char *zName;
  int nName;
  sqlite *db = pParse->db;

  if( sqlite3_malloc_failed ) goto drop_trigger_cleanup;
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){

    goto drop_trigger_cleanup;
  }

  assert( pName->nSrc==1 );
  zDb = pName->a[0].zDatabase;
  zName = pName->a[0].zName;
  nName = strlen(zName);
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
*/
void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
  Table   *pTable;
  Vdbe *v;
  sqlite *db = pParse->db;

  assert( pTrigger->iDb<db->nDb );
  pTable = sqlite3FindTable(db, pTrigger->table,db->aDb[pTrigger->iTabDb].zName);
  assert(pTable);
  assert( pTable->iDb==pTrigger->iDb || pTrigger->iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_TRIGGER;
    const char *zDb = db->aDb[pTrigger->iDb].zName;
    const char *zTab = SCHEMA_TABLE(pTrigger->iDb);







|







451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
*/
void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
  Table   *pTable;
  Vdbe *v;
  sqlite *db = pParse->db;

  assert( pTrigger->iDb<db->nDb );
  pTable = sqlite3FindTable(db,pTrigger->table,db->aDb[pTrigger->iTabDb].zName);
  assert(pTable);
  assert( pTable->iDb==pTrigger->iDb || pTrigger->iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_TRIGGER;
    const char *zDb = db->aDb[pTrigger->iDb].zName;
    const char *zTab = SCHEMA_TABLE(pTrigger->iDb);
Changes to test/capi3.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 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: capi3.test,v 1.14 2004/06/28 13:09:11 danielk1977 Exp $
#

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

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 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: capi3.test,v 1.15 2004/06/29 08:59:35 danielk1977 Exp $
#

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

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
128
129
130
131
132
133
134



135
136
137
138
139
140
141
} {SQLITE_CANTOPEN}
do_test capi3-3.4 {
  sqlite3_errmsg $db2
} {unable to open database file}
do_test capi3-3.5 {
  sqlite3_close $db2
} {SQLITE_OK}




# rename sqlite3_open ""
# rename sqlite3_open_old sqlite3_open

do_test capi3-4.1 {
  set db2 [sqlite3_open16 [utf16 test.db] {}]
  sqlite3_errcode $db2







>
>
>







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
} {SQLITE_CANTOPEN}
do_test capi3-3.4 {
  sqlite3_errmsg $db2
} {unable to open database file}
do_test capi3-3.5 {
  sqlite3_close $db2
} {SQLITE_OK}
do_test capi3-3.6 {
  sqlite3_close $db2
} {SQLITE_MISUSE}

# rename sqlite3_open ""
# rename sqlite3_open_old sqlite3_open

do_test capi3-4.1 {
  set db2 [sqlite3_open16 [utf16 test.db] {}]
  sqlite3_errcode $db2
448
449
450
451
452
453
454
455


















456
check_data $STMT capi3-6.3 {INTEGER} {1} {1.0} {1}
do_test capi3-6.3 {
  sqlite3_finalize $STMT
} {SQLITE_OK}
do_test capi3-6.4 {
  sqlite3_close $DB
} {SQLITE_OK}



















finish_test








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

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
check_data $STMT capi3-6.3 {INTEGER} {1} {1.0} {1}
do_test capi3-6.3 {
  sqlite3_finalize $STMT
} {SQLITE_OK}
do_test capi3-6.4 {
  sqlite3_close $DB
} {SQLITE_OK}

# Test what happens when the library encounters a newer file format.
# Do this by updating the file format via the btree layer.
do_test capi3-7.1 {
  set ::bt [btree_open test.db 10 0]
  btree_begin_transaction $::bt
  set meta [btree_get_meta $::bt]
  lset meta 5 2
  eval [concat btree_update_meta $::bt $meta]
  btree_commit $::bt
  btree_close $::bt
} {}
do_test capi3-7.2 {
  sqlite3 db test.db
  catchsql {
    SELECT * FROM sqlite_master;
  }
} {1 {unsupported file format}}

finish_test