/ Check-in [61b4bccd]
Login

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

Overview
Comment:Add the SQLITE_DBCONFIG_ENABLE_VIEW option, together with a "db config" command in the TCL interface that can access that option as well as all the other sqlite3_db_config() boolean options.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 61b4bccd2984f4c2cf50f58ef08677588e57aa7e079af07473b2e188d9ce4f52
User & Date: drh 2019-08-15 21:27:20
Context
2019-08-15
23:11
Fix harmless compiler warnings in the TCL interface. check-in: f17e7229 user: drh tags: trunk
21:27
Add the SQLITE_DBCONFIG_ENABLE_VIEW option, together with a "db config" command in the TCL interface that can access that option as well as all the other sqlite3_db_config() boolean options. check-in: 61b4bccd user: drh tags: trunk
14:35
Ensure that the optional "sz=N" parameter that can be manually added to the end of an sqlite_stat1 entry does not have an N value that is too small. Ticket [e4598ecbdd18bd82] check-in: 98357d8c user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/main.c.

   832    832       default: {
   833    833         static const struct {
   834    834           int op;      /* The opcode */
   835    835           u32 mask;    /* Mask of the bit in sqlite3.flags to set/clear */
   836    836         } aFlagOp[] = {
   837    837           { SQLITE_DBCONFIG_ENABLE_FKEY,           SQLITE_ForeignKeys    },
   838    838           { SQLITE_DBCONFIG_ENABLE_TRIGGER,        SQLITE_EnableTrigger  },
          839  +        { SQLITE_DBCONFIG_ENABLE_VIEW,           SQLITE_EnableView     },
   839    840           { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer  },
   840    841           { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension  },
   841    842           { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE,      SQLITE_NoCkptOnClose  },
   842    843           { SQLITE_DBCONFIG_ENABLE_QPSG,           SQLITE_EnableQPSG     },
   843    844           { SQLITE_DBCONFIG_TRIGGER_EQP,           SQLITE_TriggerEQP     },
   844    845           { SQLITE_DBCONFIG_RESET_DATABASE,        SQLITE_ResetDatabase  },
   845    846           { SQLITE_DBCONFIG_DEFENSIVE,             SQLITE_Defensive      },
................................................................................
  3071   3072     db->autoCommit = 1;
  3072   3073     db->nextAutovac = -1;
  3073   3074     db->szMmap = sqlite3GlobalConfig.szMmap;
  3074   3075     db->nextPagesize = 0;
  3075   3076     db->nMaxSorterMmap = 0x7FFFFFFF;
  3076   3077     db->flags |= SQLITE_ShortColNames
  3077   3078                    | SQLITE_EnableTrigger
         3079  +                 | SQLITE_EnableView
  3078   3080                    | SQLITE_CacheSpill
  3079   3081   
  3080   3082   /* The SQLITE_DQS compile-time option determines the default settings
  3081   3083   ** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML.
  3082   3084   **
  3083   3085   **    SQLITE_DQS     SQLITE_DBCONFIG_DQS_DDL    SQLITE_DBCONFIG_DQS_DML
  3084   3086   **    ----------     -----------------------    -----------------------

Changes to src/select.c.

  4902   4902         }
  4903   4903   #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
  4904   4904         if( IsVirtual(pTab) || pTab->pSelect ){
  4905   4905           i16 nCol;
  4906   4906           u8 eCodeOrig = pWalker->eCode;
  4907   4907           if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
  4908   4908           assert( pFrom->pSelect==0 );
         4909  +        if( pTab->pSelect && (db->flags & SQLITE_EnableView)==0 ){
         4910  +          sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited",
         4911  +              pTab->zName);
         4912  +        }
  4909   4913           pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
  4910   4914           nCol = pTab->nCol;
  4911   4915           pTab->nCol = -1;
  4912   4916           pWalker->eCode = 1;  /* Turn on Select.selId renumbering */
  4913   4917           sqlite3WalkSelect(pWalker, pFrom->pSelect);
  4914   4918           pWalker->eCode = eCodeOrig;
  4915   4919           pTab->nCol = nCol;

Changes to src/shell.c.in.

  7131   7131     if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
  7132   7132       static const struct DbConfigChoices {
  7133   7133         const char *zName;
  7134   7134         int op;
  7135   7135       } aDbConfig[] = {
  7136   7136           { "enable_fkey",        SQLITE_DBCONFIG_ENABLE_FKEY           },
  7137   7137           { "enable_trigger",     SQLITE_DBCONFIG_ENABLE_TRIGGER        },
         7138  +        { "enable_view",        SQLITE_DBCONFIG_ENABLE_VIEW           },
  7138   7139           { "fts3_tokenizer",     SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
  7139   7140           { "load_extension",     SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
  7140   7141           { "no_ckpt_on_close",   SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      },
  7141   7142           { "enable_qpsg",        SQLITE_DBCONFIG_ENABLE_QPSG           },
  7142   7143           { "trigger_eqp",        SQLITE_DBCONFIG_TRIGGER_EQP           },
  7143   7144           { "reset_database",     SQLITE_DBCONFIG_RESET_DATABASE        },
  7144   7145           { "defensive",          SQLITE_DBCONFIG_DEFENSIVE             },

Changes to src/sqlite.h.in.

  2089   2089   ** The first argument is an integer which is 0 to disable triggers,
  2090   2090   ** positive to enable triggers or negative to leave the setting unchanged.
  2091   2091   ** The second parameter is a pointer to an integer into which
  2092   2092   ** is written 0 or 1 to indicate whether triggers are disabled or enabled
  2093   2093   ** following this call.  The second parameter may be a NULL pointer, in
  2094   2094   ** which case the trigger setting is not reported back. </dd>
  2095   2095   **
         2096  +** [[SQLITE_DBCONFIG_ENABLE_VIEW]]
         2097  +** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt>
         2098  +** <dd> ^This option is used to enable or disable [CREATE VIEW | views].
         2099  +** There should be two additional arguments.
         2100  +** The first argument is an integer which is 0 to disable views,
         2101  +** positive to enable views or negative to leave the setting unchanged.
         2102  +** The second parameter is a pointer to an integer into which
         2103  +** is written 0 or 1 to indicate whether views are disabled or enabled
         2104  +** following this call.  The second parameter may be a NULL pointer, in
         2105  +** which case the view setting is not reported back. </dd>
         2106  +**
  2096   2107   ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
  2097   2108   ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
  2098   2109   ** <dd> ^This option is used to enable or disable the
  2099   2110   ** [fts3_tokenizer()] function which is part of the
  2100   2111   ** [FTS3] full-text search engine extension.
  2101   2112   ** There should be two additional arguments.
  2102   2113   ** The first argument is an integer which is 0 to disable fts3_tokenizer() or
................................................................................
  2261   2272   #define SQLITE_DBCONFIG_TRIGGER_EQP           1008 /* int int* */
  2262   2273   #define SQLITE_DBCONFIG_RESET_DATABASE        1009 /* int int* */
  2263   2274   #define SQLITE_DBCONFIG_DEFENSIVE             1010 /* int int* */
  2264   2275   #define SQLITE_DBCONFIG_WRITABLE_SCHEMA       1011 /* int int* */
  2265   2276   #define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE    1012 /* int int* */
  2266   2277   #define SQLITE_DBCONFIG_DQS_DML               1013 /* int int* */
  2267   2278   #define SQLITE_DBCONFIG_DQS_DDL               1014 /* int int* */
  2268         -#define SQLITE_DBCONFIG_MAX                   1014 /* Largest DBCONFIG */
         2279  +#define SQLITE_DBCONFIG_ENABLE_VIEW           1015 /* int int* */
         2280  +#define SQLITE_DBCONFIG_MAX                   1015 /* Largest DBCONFIG */
  2269   2281   
  2270   2282   /*
  2271   2283   ** CAPI3REF: Enable Or Disable Extended Result Codes
  2272   2284   ** METHOD: sqlite3
  2273   2285   **
  2274   2286   ** ^The sqlite3_extended_result_codes() routine enables or disables the
  2275   2287   ** [extended result codes] feature of SQLite. ^The extended result

Changes to src/sqliteInt.h.

  1533   1533   #define SQLITE_TriggerEQP     0x01000000  /* Show trigger EXPLAIN QUERY PLAN */
  1534   1534   #define SQLITE_ResetDatabase  0x02000000  /* Reset the database */
  1535   1535   #define SQLITE_LegacyAlter    0x04000000  /* Legacy ALTER TABLE behaviour */
  1536   1536   #define SQLITE_NoSchemaError  0x08000000  /* Do not report schema parse errors*/
  1537   1537   #define SQLITE_Defensive      0x10000000  /* Input SQL is likely hostile */
  1538   1538   #define SQLITE_DqsDDL         0x20000000  /* dbl-quoted strings allowed in DDL*/
  1539   1539   #define SQLITE_DqsDML         0x40000000  /* dbl-quoted strings allowed in DML*/
         1540  +#define SQLITE_EnableView     0x80000000  /* Enable the use of views */
  1540   1541   
  1541   1542   /* Flags used only if debugging */
  1542   1543   #define HI(X)  ((u64)(X)<<32)
  1543   1544   #ifdef SQLITE_DEBUG
  1544         -#define SQLITE_SqlTrace       HI(0x0001)  /* Debug print SQL as it executes */
  1545         -#define SQLITE_VdbeListing    HI(0x0002)  /* Debug listings of VDBE progs */
  1546         -#define SQLITE_VdbeTrace      HI(0x0004)  /* True to trace VDBE execution */
  1547         -#define SQLITE_VdbeAddopTrace HI(0x0008)  /* Trace sqlite3VdbeAddOp() calls */
  1548         -#define SQLITE_VdbeEQP        HI(0x0010)  /* Debug EXPLAIN QUERY PLAN */
  1549         -#define SQLITE_ParserTrace    HI(0x0020)  /* PRAGMA parser_trace=ON */
         1545  +#define SQLITE_SqlTrace       HI(0x0100000) /* Debug print SQL as it executes */
         1546  +#define SQLITE_VdbeListing    HI(0x0200000) /* Debug listings of VDBE progs */
         1547  +#define SQLITE_VdbeTrace      HI(0x0400000) /* True to trace VDBE execution */
         1548  +#define SQLITE_VdbeAddopTrace HI(0x0800000) /* Trace sqlite3VdbeAddOp() calls */
         1549  +#define SQLITE_VdbeEQP        HI(0x1000000) /* Debug EXPLAIN QUERY PLAN */
         1550  +#define SQLITE_ParserTrace    HI(0x2000000) /* PRAGMA parser_trace=ON */
  1550   1551   #endif
  1551   1552   
  1552   1553   /*
  1553   1554   ** Allowed values for sqlite3.mDbFlags
  1554   1555   */
  1555   1556   #define DBFLAG_SchemaChange   0x0001  /* Uncommitted Hash table changes */
  1556   1557   #define DBFLAG_PreferBuiltin  0x0002  /* Preference to built-in funcs */

Changes to src/tclsqlite.c.

  1913   1913     SqliteDb *pDb = (SqliteDb*)cd;
  1914   1914     int choice;
  1915   1915     int rc = TCL_OK;
  1916   1916     static const char *DB_strs[] = {
  1917   1917       "authorizer",             "backup",                "bind_fallback",
  1918   1918       "busy",                   "cache",                 "changes",
  1919   1919       "close",                  "collate",               "collation_needed",
  1920         -    "commit_hook",            "complete",              "copy",
  1921         -    "deserialize",            "enable_load_extension", "errorcode",
  1922         -    "eval",                   "exists",                "function",
  1923         -    "incrblob",               "interrupt",             "last_insert_rowid",
  1924         -    "nullvalue",              "onecolumn",             "preupdate",
  1925         -    "profile",                "progress",              "rekey",
  1926         -    "restore",                "rollback_hook",         "serialize",
  1927         -    "status",                 "timeout",               "total_changes",
  1928         -    "trace",                  "trace_v2",              "transaction",
  1929         -    "unlock_notify",          "update_hook",           "version",
  1930         -    "wal_hook",               0                        
         1920  +    "commit_hook",            "complete",              "config",
         1921  +    "copy",                   "deserialize",           "enable_load_extension",
         1922  +    "errorcode",              "eval",                  "exists",
         1923  +    "function",               "incrblob",              "interrupt",
         1924  +    "last_insert_rowid",      "nullvalue",             "onecolumn",
         1925  +    "preupdate",              "profile",               "progress",
         1926  +    "rekey",                  "restore",               "rollback_hook",
         1927  +    "serialize",              "status",                "timeout",
         1928  +    "total_changes",          "trace",                 "trace_v2",
         1929  +    "transaction",            "unlock_notify",         "update_hook",
         1930  +    "version",                "wal_hook",              0
  1931   1931     };
  1932   1932     enum DB_enum {
  1933   1933       DB_AUTHORIZER,            DB_BACKUP,               DB_BIND_FALLBACK,
  1934   1934       DB_BUSY,                  DB_CACHE,                DB_CHANGES,
  1935   1935       DB_CLOSE,                 DB_COLLATE,              DB_COLLATION_NEEDED,
  1936         -    DB_COMMIT_HOOK,           DB_COMPLETE,             DB_COPY,
  1937         -    DB_DESERIALIZE,           DB_ENABLE_LOAD_EXTENSION,DB_ERRORCODE,
  1938         -    DB_EVAL,                  DB_EXISTS,               DB_FUNCTION,
  1939         -    DB_INCRBLOB,              DB_INTERRUPT,            DB_LAST_INSERT_ROWID,
  1940         -    DB_NULLVALUE,             DB_ONECOLUMN,            DB_PREUPDATE,
  1941         -    DB_PROFILE,               DB_PROGRESS,             DB_REKEY,
  1942         -    DB_RESTORE,               DB_ROLLBACK_HOOK,        DB_SERIALIZE,
  1943         -    DB_STATUS,                DB_TIMEOUT,              DB_TOTAL_CHANGES,
  1944         -    DB_TRACE,                 DB_TRACE_V2,             DB_TRANSACTION,
  1945         -    DB_UNLOCK_NOTIFY,         DB_UPDATE_HOOK,          DB_VERSION,
  1946         -    DB_WAL_HOOK             
         1936  +    DB_COMMIT_HOOK,           DB_COMPLETE,             DB_CONFIG,
         1937  +    DB_COPY,                  DB_DESERIALIZE,          DB_ENABLE_LOAD_EXTENSION,
         1938  +    DB_ERRORCODE,             DB_EVAL,                 DB_EXISTS,
         1939  +    DB_FUNCTION,              DB_INCRBLOB,             DB_INTERRUPT,
         1940  +    DB_LAST_INSERT_ROWID,     DB_NULLVALUE,            DB_ONECOLUMN,
         1941  +    DB_PREUPDATE,             DB_PROFILE,              DB_PROGRESS,
         1942  +    DB_REKEY,                 DB_RESTORE,              DB_ROLLBACK_HOOK,
         1943  +    DB_SERIALIZE,             DB_STATUS,               DB_TIMEOUT,
         1944  +    DB_TOTAL_CHANGES,         DB_TRACE,                DB_TRACE_V2,
         1945  +    DB_TRANSACTION,           DB_UNLOCK_NOTIFY,        DB_UPDATE_HOOK,
         1946  +    DB_VERSION,               DB_WAL_HOOK             
  1947   1947     };
  1948   1948     /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
  1949   1949   
  1950   1950     if( objc<2 ){
  1951   1951       Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
  1952   1952       return TCL_ERROR;
  1953   1953     }
................................................................................
  2326   2326       }
  2327   2327       isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
  2328   2328       pResult = Tcl_GetObjResult(interp);
  2329   2329       Tcl_SetBooleanObj(pResult, isComplete);
  2330   2330   #endif
  2331   2331       break;
  2332   2332     }
         2333  +
         2334  +  /*    $db config ?OPTION? ?BOOLEAN?
         2335  +  **
         2336  +  ** Configure the database connection using the sqlite3_db_config()
         2337  +  ** interface.
         2338  +  */
         2339  +  case DB_CONFIG: {
         2340  +    static const struct DbConfigChoices {
         2341  +      const char *zName;
         2342  +      int op;
         2343  +    } aDbConfig[] = {
         2344  +        { "enable_fkey",        SQLITE_DBCONFIG_ENABLE_FKEY           },
         2345  +        { "enable_trigger",     SQLITE_DBCONFIG_ENABLE_TRIGGER        },
         2346  +        { "enable_view",        SQLITE_DBCONFIG_ENABLE_VIEW           },
         2347  +        { "fts3_tokenizer",     SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
         2348  +        { "load_extension",     SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
         2349  +        { "no_ckpt_on_close",   SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      },
         2350  +        { "enable_qpsg",        SQLITE_DBCONFIG_ENABLE_QPSG           },
         2351  +        { "trigger_eqp",        SQLITE_DBCONFIG_TRIGGER_EQP           },
         2352  +        { "reset_database",     SQLITE_DBCONFIG_RESET_DATABASE        },
         2353  +        { "defensive",          SQLITE_DBCONFIG_DEFENSIVE             },
         2354  +        { "writable_schema",    SQLITE_DBCONFIG_WRITABLE_SCHEMA       },
         2355  +        { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE    },
         2356  +        { "dqs_dml",            SQLITE_DBCONFIG_DQS_DML               },
         2357  +        { "dqs_ddl",            SQLITE_DBCONFIG_DQS_DDL               },
         2358  +    };
         2359  +    Tcl_Obj *pResult;
         2360  +    int ii;
         2361  +    if( objc>4 ){
         2362  +      Tcl_WrongNumArgs(interp, 2, objv, "?OPTION? ?BOOLEAN?");
         2363  +      return TCL_ERROR;
         2364  +    }
         2365  +    if( objc==2 ){
         2366  +      /* With no arguments, list all configuration options and with the
         2367  +      ** current value */
         2368  +      pResult = Tcl_NewListObj(0,0);
         2369  +      for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){
         2370  +        int v = 0;
         2371  +        int rc = sqlite3_db_config(pDb->db, aDbConfig[ii].op, -1, &v);
         2372  +        if( rc!=SQLITE_OK ) continue;
         2373  +        Tcl_ListObjAppendElement(interp, pResult,
         2374  +           Tcl_NewStringObj(aDbConfig[ii].zName,-1));
         2375  +        Tcl_ListObjAppendElement(interp, pResult,
         2376  +           Tcl_NewIntObj(v));
         2377  +      }
         2378  +    }else{
         2379  +      const char *zOpt = Tcl_GetString(objv[2]);
         2380  +      int rc;
         2381  +      int onoff = -1;
         2382  +      int v = 0;
         2383  +      if( zOpt[0]=='-' ) zOpt++;
         2384  +      for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){
         2385  +        if( strcmp(aDbConfig[ii].zName, zOpt)==0 ) break;
         2386  +      }
         2387  +      if( ii>=sizeof(aDbConfig)/sizeof(aDbConfig[0]) ){
         2388  +        Tcl_AppendResult(interp, "unknown config option: \"", zOpt,
         2389  +                                "\"", (void*)0);
         2390  +        return TCL_ERROR;
         2391  +      }
         2392  +      if( objc==4 ){
         2393  +        if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ){
         2394  +          return TCL_ERROR;
         2395  +        }
         2396  +      }
         2397  +      rc = sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v);
         2398  +      pResult = Tcl_NewIntObj(v);
         2399  +    }
         2400  +    Tcl_SetObjResult(interp, pResult);
         2401  +    break;
         2402  +  }
  2333   2403   
  2334   2404     /*    $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
  2335   2405     **
  2336   2406     ** Copy data into table from filename, optionally using SEPARATOR
  2337   2407     ** as column separators.  If a column contains a null string, or the
  2338   2408     ** value of NULLINDICATOR, a NULL is inserted for the column.
  2339   2409     ** conflict-algorithm is one of the sqlite conflict algorithms:

Changes to test/tclsqlite.test.

    38     38     set v [catch {sqlite3} msg]
    39     39     regsub {really_sqlite3} $msg {sqlite3} msg
    40     40     lappend v $msg
    41     41   } [list 1 "wrong # args: should be \"$r\""]
    42     42   do_test tcl-1.2 {
    43     43     set v [catch {db bogus} msg]
    44     44     lappend v $msg
    45         -} {1 {bad option "bogus": must be authorizer, backup, bind_fallback, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, deserialize, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}}
           45  +} {1 {bad option "bogus": must be authorizer, backup, bind_fallback, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, config, copy, deserialize, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}}
    46     46   do_test tcl-1.2.1 {
    47     47     set v [catch {db cache bogus} msg]
    48     48     lappend v $msg
    49     49   } {1 {bad option "bogus": must be flush or size}}
    50     50   do_test tcl-1.2.2 {
    51     51     set v [catch {db cache} msg]
    52     52     lappend v $msg

Changes to test/view.test.

    34     34   do_test view-1.1 {
    35     35     execsql {
    36     36       BEGIN;
    37     37       CREATE VIEW IF NOT EXISTS v1 AS SELECT a,b FROM t1;
    38     38       SELECT * FROM v1 ORDER BY a;
    39     39     }
    40     40   } {1 2 4 5 7 8}
           41  +do_test view-1.1.100 {
           42  +  db config enable_view off
           43  +  catchsql {
           44  +    SELECT * FROM v1 ORDER BY a;
           45  +  }
           46  +} {1 {access to view "v1" prohibited}}
           47  +do_test view-1.1.110 {
           48  +  db config enable_view on
           49  +  catchsql {
           50  +    SELECT * FROM v1 ORDER BY a;
           51  +  }
           52  +} {0 {1 2 4 5 7 8}}
    41     53   do_test view-1.2 {
    42     54     catchsql {
    43     55       ROLLBACK;
    44     56       SELECT * FROM v1 ORDER BY a;
    45     57     }
    46     58   } {1 {no such table: v1}}
    47     59   do_test view-1.3 {