SQLite

Check-in [0e1d8d14a1]
Login

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

Overview
Comment:Do not allow indexing of any table whose name begins with "sqlite_". Ticket #3284. Improve handling of databases with malformed schemas - just in case somebody has actually indexed a system table. (CVS 5553)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0e1d8d14a153483e65bd0246d23db2b823a122d1
User & Date: drh 2008-08-11 18:44:58.000
Context
2008-08-11
19:12
Make the CLI more tolerant of malformed schemas by setting the writable_schema pragma prior to running the ".dump" command. (CVS 5554) (check-in: 860babd841 user: drh tags: trunk)
18:44
Do not allow indexing of any table whose name begins with "sqlite_". Ticket #3284. Improve handling of databases with malformed schemas - just in case somebody has actually indexed a system table. (CVS 5553) (check-in: 0e1d8d14a1 user: drh tags: trunk)
18:29
The GCC magic to warn about experimental interfaces does not work on gcc version 4.1.0. Add #ifdefs to work around this. (CVS 5552) (check-in: 90cae83169 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/build.c.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.494 2008/08/06 13:47:41 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.495 2008/08/11 18:44:58 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
      goto exit_drop_table;
    }
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
      goto exit_drop_table;
    }
  }
#endif
  if( pTab->readOnly || pTab==db->aDb[iDb].pSchema->pSeqTab ){
    sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
    goto exit_drop_table;
  }

#ifndef SQLITE_OMIT_VIEW
  /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
  ** on a table.







|







2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
      goto exit_drop_table;
    }
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
      goto exit_drop_table;
    }
  }
#endif
  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
    sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
    goto exit_drop_table;
  }

#ifndef SQLITE_OMIT_VIEW
  /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
  ** on a table.
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
    pTab = pParse->pNewTable;
    if( !pTab ) goto exit_create_index;
    iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  }
  pDb = &db->aDb[iDb];

  if( pTab==0 || pParse->nErr ) goto exit_create_index;
  if( pTab->readOnly ){
    sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
    goto exit_create_index;
  }
#ifndef SQLITE_OMIT_VIEW
  if( pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "views may not be indexed");
    goto exit_create_index;







|







2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
    pTab = pParse->pNewTable;
    if( !pTab ) goto exit_create_index;
    iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  }
  pDb = &db->aDb[iDb];

  if( pTab==0 || pParse->nErr ) goto exit_create_index;
  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
    sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
    goto exit_create_index;
  }
#ifndef SQLITE_OMIT_VIEW
  if( pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "views may not be indexed");
    goto exit_create_index;
Changes to src/prepare.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.91 2008/08/02 03:50:39 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Fill the InitData structure with an error message that indicates
** that the database is corrupt.
*/
static void corruptSchema(
  InitData *pData,     /* Initialization context */
  const char *zObj,    /* Object being parsed at the point of error */
  const char *zExtra   /* Error information */
){

  if( !pData->db->mallocFailed ){
    if( zObj==0 ) zObj = "?";
    sqlite3SetString(pData->pzErrMsg, pData->db,
       "malformed database schema (%s)", zObj);
    if( zExtra && zExtra[0] ){
      *pData->pzErrMsg = sqlite3MAppendf(pData->db, *pData->pzErrMsg, "%s - %s",
                                  *pData->pzErrMsg, zExtra);
    }







|













>
|







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
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.92 2008/08/11 18:44:58 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Fill the InitData structure with an error message that indicates
** that the database is corrupt.
*/
static void corruptSchema(
  InitData *pData,     /* Initialization context */
  const char *zObj,    /* Object being parsed at the point of error */
  const char *zExtra   /* Error information */
){
  sqlite3 *db = pData->db;
  if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
    if( zObj==0 ) zObj = "?";
    sqlite3SetString(pData->pzErrMsg, pData->db,
       "malformed database schema (%s)", zObj);
    if( zExtra && zExtra[0] ){
      *pData->pzErrMsg = sqlite3MAppendf(pData->db, *pData->pzErrMsg, "%s - %s",
                                  *pData->pzErrMsg, zExtra);
    }
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
*/
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
  InitData *pData = (InitData*)pInit;
  sqlite3 *db = pData->db;
  int iDb = pData->iDb;

  assert( sqlite3_mutex_held(db->mutex) );
  pData->rc = SQLITE_OK;
  DbClearProperty(db, iDb, DB_Empty);
  if( db->mallocFailed ){
    corruptSchema(pData, argv[0], 0);
    return SQLITE_NOMEM;
  }

  assert( argc==3 );







<







54
55
56
57
58
59
60

61
62
63
64
65
66
67
*/
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
  InitData *pData = (InitData*)pInit;
  sqlite3 *db = pData->db;
  int iDb = pData->iDb;

  assert( sqlite3_mutex_held(db->mutex) );

  DbClearProperty(db, iDb, DB_Empty);
  if( db->mallocFailed ){
    corruptSchema(pData, argv[0], 0);
    return SQLITE_NOMEM;
  }

  assert( argc==3 );
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
      pData->rc = rc;
      if( rc==SQLITE_NOMEM ){
        db->mallocFailed = 1;
      }else if( rc!=SQLITE_INTERRUPT ){
        corruptSchema(pData, argv[0], zErr);
      }
      sqlite3DbFree(db, zErr);
      return 1;
    }
  }else if( argv[0]==0 ){
    corruptSchema(pData, 0, 0);
  }else{
    /* If the SQL column is blank it means this is an index that
    ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
    ** constraint for a CREATE TABLE.  The index should have already







<







93
94
95
96
97
98
99

100
101
102
103
104
105
106
      pData->rc = rc;
      if( rc==SQLITE_NOMEM ){
        db->mallocFailed = 1;
      }else if( rc!=SQLITE_INTERRUPT ){
        corruptSchema(pData, argv[0], zErr);
      }
      sqlite3DbFree(db, zErr);

    }
  }else if( argv[0]==0 ){
    corruptSchema(pData, 0, 0);
  }else{
    /* If the SQL column is blank it means this is an index that
    ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
    ** constraint for a CREATE TABLE.  The index should have already
189
190
191
192
193
194
195

196
197
198
199
200
201
202
203
204
205
206
207
  /* Construct the schema tables.  */
  azArg[0] = zMasterName;
  azArg[1] = "1";
  azArg[2] = zMasterSchema;
  azArg[3] = 0;
  initData.db = db;
  initData.iDb = iDb;

  initData.pzErrMsg = pzErrMsg;
  (void)sqlite3SafetyOff(db);
  rc = sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
  (void)sqlite3SafetyOn(db);
  if( rc ){
    rc = initData.rc;
    goto error_out;
  }
  pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName);
  if( pTab ){
    pTab->readOnly = 1;
  }







>


|

|







188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
  /* Construct the schema tables.  */
  azArg[0] = zMasterName;
  azArg[1] = "1";
  azArg[2] = zMasterSchema;
  azArg[3] = 0;
  initData.db = db;
  initData.iDb = iDb;
  initData.rc = SQLITE_OK;
  initData.pzErrMsg = pzErrMsg;
  (void)sqlite3SafetyOff(db);
  sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
  (void)sqlite3SafetyOn(db);
  if( initData.rc ){
    rc = initData.rc;
    goto error_out;
  }
  pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName);
  if( pTab ){
    pTab->readOnly = 1;
  }
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
      db->xAuth = 0;
#endif
      rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
#ifndef SQLITE_OMIT_AUTHORIZATION
      db->xAuth = xAuth;
    }
#endif
    if( rc==SQLITE_ABORT ) rc = initData.rc;
    (void)sqlite3SafetyOn(db);
    sqlite3DbFree(db, zSql);
#ifndef SQLITE_OMIT_ANALYZE
    if( rc==SQLITE_OK ){
      sqlite3AnalysisLoad(db, iDb);
    }
#endif







|







334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
      db->xAuth = 0;
#endif
      rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
#ifndef SQLITE_OMIT_AUTHORIZATION
      db->xAuth = xAuth;
    }
#endif
    if( rc==SQLITE_OK ) rc = initData.rc;
    (void)sqlite3SafetyOn(db);
    sqlite3DbFree(db, zSql);
#ifndef SQLITE_OMIT_ANALYZE
    if( rc==SQLITE_OK ){
      sqlite3AnalysisLoad(db, iDb);
    }
#endif
Changes to src/vdbe.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.772 2008/08/02 15:10:09 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.773 2008/08/11 18:44:58 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
4135
4136
4137
4138
4139
4140
4141

4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
  zSql = sqlite3MPrintf(db,
     "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s",
     db->aDb[iDb].zName, zMaster, pOp->p4.z);
  if( zSql==0 ) goto no_mem;
  (void)sqlite3SafetyOff(db);
  assert( db->init.busy==0 );
  db->init.busy = 1;

  assert( !db->mallocFailed );
  rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
  if( rc==SQLITE_ABORT ) rc = initData.rc;
  sqlite3DbFree(db, zSql);
  db->init.busy = 0;
  (void)sqlite3SafetyOn(db);
  if( rc==SQLITE_NOMEM ){
    goto no_mem;
  }
  break;  







>


|







4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
  zSql = sqlite3MPrintf(db,
     "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s",
     db->aDb[iDb].zName, zMaster, pOp->p4.z);
  if( zSql==0 ) goto no_mem;
  (void)sqlite3SafetyOff(db);
  assert( db->init.busy==0 );
  db->init.busy = 1;
  initData.rc = SQLITE_OK;
  assert( !db->mallocFailed );
  rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
  if( rc==SQLITE_OK ) rc = initData.rc;
  sqlite3DbFree(db, zSql);
  db->init.busy = 0;
  (void)sqlite3SafetyOn(db);
  if( rc==SQLITE_NOMEM ){
    goto no_mem;
  }
  break;  
Changes to src/vdbeapi.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.
**
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
**
** $Id: vdbeapi.c,v 1.138 2008/08/02 03:50:39 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
** The following structure contains pointers to the end points of a







|







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.
**
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
**
** $Id: vdbeapi.c,v 1.139 2008/08/11 18:44:58 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
** The following structure contains pointers to the end points of a
429
430
431
432
433
434
435
436


437
438
439
440
441
442
443
  assert(p);
  if( p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_MISUSE;
  }

  /* Assert that malloc() has not failed */
  db = p->db;
  assert( !db->mallocFailed );



  if( p->pc<=0 && p->expired ){
    if( p->rc==SQLITE_OK ){
      p->rc = SQLITE_SCHEMA;
    }
    rc = SQLITE_ERROR;
    goto end_of_step;







|
>
>







429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
  assert(p);
  if( p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_MISUSE;
  }

  /* Assert that malloc() has not failed */
  db = p->db;
  if( db->mallocFailed ){
    return SQLITE_NOMEM;
  }

  if( p->pc<=0 && p->expired ){
    if( p->rc==SQLITE_OK ){
      p->rc = SQLITE_SCHEMA;
    }
    rc = SQLITE_ERROR;
    goto end_of_step;
Changes to test/analyze.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2005 July 22
#
# 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.
# This file implements tests for the ANALYZE command.
#
# $Id: analyze.test,v 1.8 2008/08/01 18:47:02 drh Exp $

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

# There is nothing to test if ANALYZE is disable for this build.
#
ifcapable {!analyze} {













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2005 July 22
#
# 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.
# This file implements tests for the ANALYZE command.
#
# $Id: analyze.test,v 1.9 2008/08/11 18:44:58 drh Exp $

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

# There is nothing to test if ANALYZE is disable for this build.
#
ifcapable {!analyze} {
57
58
59
60
61
62
63










64
65
66
67
68
69
70
  }
} {0 {}}
do_test analyze-1.6 {
  execsql {
    SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1'
  }
} {1}










do_test analyze-1.7 {
  execsql {
    SELECT * FROM sqlite_stat1
  }
} {}
do_test analyze-1.8 {
  catchsql {







>
>
>
>
>
>
>
>
>
>







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
  }
} {0 {}}
do_test analyze-1.6 {
  execsql {
    SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1'
  }
} {1}
do_test analyze-1.6.2 {
  catchsql {
    CREATE INDEX stat1idx ON sqlite_stat1(idx);
  }
} {1 {table sqlite_stat1 may not be indexed}}
do_test analyze-1.6.3 {
  catchsql {
    CREATE INDEX main.stat1idx ON SQLite_stat1(idx);
  }
} {1 {table sqlite_stat1 may not be indexed}}
do_test analyze-1.7 {
  execsql {
    SELECT * FROM sqlite_stat1
  }
} {}
do_test analyze-1.8 {
  catchsql {
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296

# This test corrupts the database file so it must be the last test
# in the series.
#
do_test analyze-99.1 {
  execsql {
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET sql='nonsense';
  }
  db close
  sqlite3 db test.db
  catchsql {
    ANALYZE
  }
} {1 {malformed database schema (sqlite_stat1) - near "nonsense": syntax error}}


finish_test







|










289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

# This test corrupts the database file so it must be the last test
# in the series.
#
do_test analyze-99.1 {
  execsql {
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET sql='nonsense' WHERE name='sqlite_stat1';
  }
  db close
  sqlite3 db test.db
  catchsql {
    ANALYZE
  }
} {1 {malformed database schema (sqlite_stat1) - near "nonsense": syntax error}}


finish_test
Changes to test/autoinc.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2004 November 12
#
# 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 is testing the AUTOINCREMENT features.
#
# $Id: autoinc.test,v 1.12 2008/05/29 03:20:59 drh Exp $
#

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

# If the library is not compiled with autoincrement support then
# skip all tests in this file.













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2004 November 12
#
# 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 is testing the AUTOINCREMENT features.
#
# $Id: autoinc.test,v 1.13 2008/08/11 18:44:58 drh Exp $
#

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

# If the library is not compiled with autoincrement support then
# skip all tests in this file.
46
47
48
49
50
51
52





53
54
55
56
57
58
59
# The SQLITE_SEQUENCE table is initially empty
#
do_test autoinc-1.3 {
  execsql {
    SELECT * FROM sqlite_sequence;
  }
} {}






# Close and reopen the database.  Verify that everything is still there.
#
do_test autoinc-1.4 {
  db close
  sqlite3 db test.db
  execsql {







>
>
>
>
>







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# The SQLITE_SEQUENCE table is initially empty
#
do_test autoinc-1.3 {
  execsql {
    SELECT * FROM sqlite_sequence;
  }
} {}
do_test autoinc-1.3.1 {
  catchsql {
    CREATE INDEX seqidx ON sqlite_sequence(name)
  }
} {1 {table sqlite_sequence may not be indexed}}

# Close and reopen the database.  Verify that everything is still there.
#
do_test autoinc-1.4 {
  db close
  sqlite3 db test.db
  execsql {
Changes to test/trigger7.test.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to increase coverage of trigger.c.
#
# $Id: trigger7.test,v 1.2 2008/03/19 13:03:34 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable {!trigger} {
  finish_test
  return
}







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests to increase coverage of trigger.c.
#
# $Id: trigger7.test,v 1.3 2008/08/11 18:44:58 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable {!trigger} {
  finish_test
  return
}
112
113
114
115
116
117
118
119
120
121
    UPDATE sqlite_master SET sql='nonsense';
  }
  db close
  sqlite3 db test.db
  catchsql {
    DROP TRIGGER t2r5
  }
} {1 {malformed database schema (t1) - near "nonsense": syntax error}}

finish_test







|


112
113
114
115
116
117
118
119
120
121
    UPDATE sqlite_master SET sql='nonsense';
  }
  db close
  sqlite3 db test.db
  catchsql {
    DROP TRIGGER t2r5
  }
} {1 {malformed database schema (t2r12) - near "nonsense": syntax error}}

finish_test