/ Check-in [1c1d24ed]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Turn on defensive mode for running test scripts. Does not yet work.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | read-only-shadow
Files: files | file ages | folders
SHA3-256: 1c1d24edbb732f2a2002a741c7a7afdd010b67e1b5e6d90ff36c6428897e7612
User & Date: drh 2018-11-06 15:57:59
Context
2018-11-06
19:26
Enable DEFENSIVE mode by default for tests. This requires lots of case of turning DEFENSIVE off in order to dodgy things to the database for testing purposes. No all of those cases are yet handled, so "make test" does not run to completion. check-in: a1d6c671 user: drh tags: read-only-shadow
15:57
Turn on defensive mode for running test scripts. Does not yet work. check-in: 1c1d24ed user: drh tags: read-only-shadow
14:03
Only allow shadow table to be written from within a recursive SQL call. Omit the SQLITE_PREPARE_SHADOW flag. Some tests are failing because the tests depend on being able to write to shadow tables. check-in: d890c658 user: drh tags: read-only-shadow
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/fts5/test/fts5aa.test.

405
406
407
408
409
410
411

412
413
414
415
416
417
418
  }
  set nRow
} {200}

do_execsql_test 15.0 {
  INSERT INTO t1(t1) VALUES('integrity-check');
}

do_execsql_test 15.1 {
  UPDATE t1_content SET c1 = 'xyz xyz xyz xyz xyz abc' WHERE rowid = 1;
}
do_catchsql_test 15.2 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}








>







405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
  }
  set nRow
} {200}

do_execsql_test 15.0 {
  INSERT INTO t1(t1) VALUES('integrity-check');
}
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 15.1 {
  UPDATE t1_content SET c1 = 'xyz xyz xyz xyz xyz abc' WHERE rowid = 1;
}
do_catchsql_test 15.2 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}

Changes to src/delete.c.

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

/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is
** writable return 0;
*/
int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){

  /* A table is not writable under the following circumstances:
  **
  **   1) It is a virtual table and no implementation of the xUpdate method
  **      has been provided, or
  **   2) It is a system table (i.e. sqlite_master), this call is not
  **      part of a nested parse and writable_schema pragma has not 
  **      been specified.
  **   3) The table is a shadow table and the current sqlite3_prepare()
  **      is for a top-level SQL statement, not a nested SQL statement
  **      issued by a virtual table implementation.
  **
  ** In either case leave an error message in pParse and return non-zero.
  */
  if( ( IsVirtual(pTab) 
     && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
   || ( (pTab->tabFlags & TF_Readonly)!=0
     && sqlite3WritableSchema(pParse->db)==0
     && pParse->nested==0)
   || ( (pTab->tabFlags & TF_Shadow)!=0

     && pParse->db->nVdbeExec==0)
  ){
    sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
    return 1;
  }

#ifndef SQLITE_OMIT_VIEW
  if( !viewOk && pTab->pSelect ){







>







|
|
|




|

|


>
|







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

/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is
** writable return 0;
*/
int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
  sqlite3 *db = pParse->db;
  /* A table is not writable under the following circumstances:
  **
  **   1) It is a virtual table and no implementation of the xUpdate method
  **      has been provided, or
  **   2) It is a system table (i.e. sqlite_master), this call is not
  **      part of a nested parse and writable_schema pragma has not 
  **      been specified.
  **   3) The table is a shadow table, the database connection is in
  **      defensive mode, and the current sqlite3_prepare()
  **      is for a top-level SQL statement.
  **
  ** In either case leave an error message in pParse and return non-zero.
  */
  if( ( IsVirtual(pTab) 
     && sqlite3GetVTable(db, pTab)->pMod->pModule->xUpdate==0 )
   || ( (pTab->tabFlags & TF_Readonly)!=0
     && sqlite3WritableSchema(db)==0
     && pParse->nested==0)
   || ( (pTab->tabFlags & TF_Shadow)!=0
     && (db->flags & SQLITE_Defensive)!=0
     && db->nVdbeExec==0)
  ){
    sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
    return 1;
  }

#ifndef SQLITE_OMIT_VIEW
  if( !viewOk && pTab->pSelect ){

Changes to test/tester.tcl.

132
133
134
135
136
137
138

139
140
141
142
143
144
145
      set res
    } else {
      # This command is not opening a new database connection. Pass the
      # arguments through to the C implementation as the are.
      #
      uplevel 1 sqlite_orig $args
    }

  }
}

proc getFileRetries {} {
  if {![info exists ::G(file-retries)]} {
    #
    # NOTE: Return the default number of retries for [file] operations.  A







>







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
      set res
    } else {
      # This command is not opening a new database connection. Pass the
      # arguments through to the C implementation as the are.
      #
      uplevel 1 sqlite_orig $args
    }
    sqlite3_db_config [lindex $args 0] DEFENSIVE 1
  }
}

proc getFileRetries {} {
  if {![info exists ::G(file-retries)]} {
    #
    # NOTE: Return the default number of retries for [file] operations.  A