/ Check-in [6557c407]
Login

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

Overview
Comment:Add the experimental "query_only" pragma.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6557c407983b067449deb76bc4c5248de64e07dc
User & Date: drh 2013-07-11 15:22:31
Context
2013-07-11
19:04
Change the description of how sqlite3_progress_handler() works so that the N parameter is "approximate". This aligns with the current implementation. This is a documentation change only. No changes to code. check-in: 7d829bde user: drh tags: trunk
15:31
Merge recent trunk changes (such as the query_only PRAGMA, the defer_foreign_keys PRAGMA, and the SQLITE_DBSTATUS_DEFERRED_FKS parameter to sqlite3_db_status()) into the sessions branch. check-in: 8dfc0b78 user: drh tags: sessions
15:22
Add the experimental "query_only" pragma. check-in: 6557c407 user: drh tags: trunk
15:03
Add the "defer_foreign_keys" pragma and the SQLITE_DBSTATUS_DEFERRED_FKS value for sqlite3_db_status(). This is a cherry-pick of a sequence of five checkins in the sessions branch between [1d44e5d3c2] and [d39e65fe70]. check-in: 527121ac user: drh tags: trunk
2013-07-10
13:33
Experimental "PRAGMA query_only=BOOLEAN" statement that is able to turn write capabilities on and off. Closed-Leaf check-in: ece960c4 user: drh tags: query_only
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/pragma.c.

173
174
175
176
177
178
179

180
181
182
183
184
185
186
    { "short_column_names",       SQLITE_ShortColNames },
    { "count_changes",            SQLITE_CountRows     },
    { "empty_result_callbacks",   SQLITE_NullCallback  },
    { "legacy_file_format",       SQLITE_LegacyFileFmt },
    { "fullfsync",                SQLITE_FullFSync     },
    { "checkpoint_fullfsync",     SQLITE_CkptFullFSync },
    { "reverse_unordered_selects", SQLITE_ReverseOrder  },

#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
    { "automatic_index",          SQLITE_AutoIndex     },
#endif
#ifdef SQLITE_DEBUG
    { "sql_trace",                SQLITE_SqlTrace      },
    { "vdbe_listing",             SQLITE_VdbeListing   },
    { "vdbe_trace",               SQLITE_VdbeTrace     },







>







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
    { "short_column_names",       SQLITE_ShortColNames },
    { "count_changes",            SQLITE_CountRows     },
    { "empty_result_callbacks",   SQLITE_NullCallback  },
    { "legacy_file_format",       SQLITE_LegacyFileFmt },
    { "fullfsync",                SQLITE_FullFSync     },
    { "checkpoint_fullfsync",     SQLITE_CkptFullFSync },
    { "reverse_unordered_selects", SQLITE_ReverseOrder  },
    { "query_only",               SQLITE_QueryOnly     },
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
    { "automatic_index",          SQLITE_AutoIndex     },
#endif
#ifdef SQLITE_DEBUG
    { "sql_trace",                SQLITE_SqlTrace      },
    { "vdbe_listing",             SQLITE_VdbeListing   },
    { "vdbe_trace",               SQLITE_VdbeTrace     },

Changes to src/sqliteInt.h.

1007
1008
1009
1010
1011
1012
1013


1014
1015
1016
1017
1018
1019
1020
#define SQLITE_RecTriggers    0x00020000  /* Enable recursive triggers */
#define SQLITE_ForeignKeys    0x00040000  /* Enforce foreign key constraints  */
#define SQLITE_AutoIndex      0x00080000  /* Enable automatic indexes */
#define SQLITE_PreferBuiltin  0x00100000  /* Preference to built-in funcs */
#define SQLITE_LoadExtension  0x00200000  /* Enable load_extension */
#define SQLITE_EnableTrigger  0x00400000  /* True to enable triggers */
#define SQLITE_DeferFKs       0x00800000  /* Defer all FK constraints */



/*
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
*/
#define SQLITE_QueryFlattener 0x0001   /* Query flattening */







>
>







1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
#define SQLITE_RecTriggers    0x00020000  /* Enable recursive triggers */
#define SQLITE_ForeignKeys    0x00040000  /* Enforce foreign key constraints  */
#define SQLITE_AutoIndex      0x00080000  /* Enable automatic indexes */
#define SQLITE_PreferBuiltin  0x00100000  /* Preference to built-in funcs */
#define SQLITE_LoadExtension  0x00200000  /* Enable load_extension */
#define SQLITE_EnableTrigger  0x00400000  /* True to enable triggers */
#define SQLITE_DeferFKs       0x00800000  /* Defer all FK constraints */
#define SQLITE_QueryOnly      0x01000000  /* Disable database changes */


/*
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
*/
#define SQLITE_QueryFlattener 0x0001   /* Query flattening */

Changes to src/vdbe.c.

2944
2945
2946
2947
2948
2949
2950




2951
2952
2953
2954
2955
2956
2957
case OP_Transaction: {
  Btree *pBt;

  assert( p->bIsReader );
  assert( p->readOnly==0 || pOp->p2==0 );
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );




  pBt = db->aDb[pOp->p1].pBt;

  if( pBt ){
    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
    if( rc==SQLITE_BUSY ){
      p->pc = pc;
      p->rc = rc = SQLITE_BUSY;







>
>
>
>







2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
case OP_Transaction: {
  Btree *pBt;

  assert( p->bIsReader );
  assert( p->readOnly==0 || pOp->p2==0 );
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
  if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
    rc = SQLITE_READONLY;
    goto abort_due_to_error;
  }
  pBt = db->aDb[pOp->p1].pBt;

  if( pBt ){
    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
    if( rc==SQLITE_BUSY ){
      p->pc = pc;
      p->rc = rc = SQLITE_BUSY;

Changes to test/fkey6.test.

1
2
3
4
5
6
7
8
# 2012 December 17
#
# 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.
|







1
2
3
4
5
6
7
8
# 2013-07-11
#
# 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.

Added test/queryonly.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
# 2013-07-11
#
# 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 tests the "query_only" pragma.
#

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

do_execsql_test queryonly-1.1 {
  CREATE TABLE t1(a);
  INSERT INTO t1 VALUES(123),(456);
  SELECT a FROM t1 ORDER BY a;
} {123 456}
do_execsql_test queryonly-1.2 {
  PRAGMA query_only;
} {0}
do_execsql_test queryonly-1.3 {
  PRAGMA query_only=ON;
  PRAGMA query_only;
} {1}
do_test queryonly-1.4 {
  catchsql {INSERT INTO t1 VALUES(789);}
} {1 {attempt to write a readonly database}}
do_test queryonly-1.5 {
  catchsql {DELETE FROM t1;}
} {1 {attempt to write a readonly database}}
do_test queryonly-1.6 {
  catchsql {UPDATE t1 SET a=a+1;}
} {1 {attempt to write a readonly database}}
do_test queryonly-1.7 {
  catchsql {CREATE TABLE t2(b);}
} {1 {attempt to write a readonly database}}
do_test queryonly-1.8 {
  catchsql {CREATE INDEX t1a ON t1(a);}
} {1 {attempt to write a readonly database}}
do_test queryonly-1.9 {
  catchsql {DROP TABLE t1;}
} {1 {attempt to write a readonly database}}
do_test queryonly-1.10 {
  catchsql {ANALYZE;}
} {1 {attempt to write a readonly database}}
do_execsql_test queryonly-1.11 {
  SELECT a FROM t1 ORDER BY a;
} {123 456}

do_execsql_test queryonly-2.2 {
  PRAGMA query_only;
} {1}
do_execsql_test queryonly-2.3 {
  PRAGMA query_only=OFF;
  PRAGMA query_only;
} {0}
do_execsql_test queryonly-2.4 {
  INSERT INTO t1 VALUES(789);
  SELECT a FROM t1 ORDER BY a;
} {123 456 789}
do_execsql_test queryonly-2.5 {
  UPDATE t1 SET a=a+1;
  SELECT a FROM t1 ORDER BY a;
} {124 457 790}

finish_test