/ Check-in [6e4968b0]
Login

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

Overview
Comment:Performance improvement in subroutine that decides whether or not a table is read-only.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | read-only-shadow
Files: files | file ages | folders
SHA3-256:6e4968b00507c4fdbe7e3c91f3f9cd61c6f1848092ddcf306f9fcb101a47fce7
User & Date: drh 2018-11-07 16:46:43
Context
2018-11-08
17:32
Improved documentation for SQLITE_DBCONFIG_DEFENSIVE. Add a NEVER() macro on an unreachable branch. check-in: 9292d335 user: drh tags: read-only-shadow
2018-11-07
16:46
Performance improvement in subroutine that decides whether or not a table is read-only. check-in: 6e4968b0 user: drh tags: read-only-shadow
16:12
Merge the onefile permutation fix from trunk. check-in: e543bff8 user: drh tags: read-only-shadow
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/delete.c.

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
73
74
75
76









77
78
79
80
81
82
83
84
85
86
87
    pTab->nTabRef++;
  }
  if( sqlite3IndexedByLookup(pParse, pItem) ){
    pTab = 0;
  }
  return pTab;
}

/*
** 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
     && db->pVtabCtx==0)
  ){









    sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
    return 1;
  }

#ifndef SQLITE_OMIT_VIEW
  if( !viewOk && pTab->pSelect ){
    sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
    return 1;
  }
#endif
  return 0;








|
<
<
<
|
<
<
<
>
|
|
|
>
|
|
|
>
|
|
|
<
<
|
>
>
|
|
>
>
>
|
|
<
>
|
|
|
|
<
>
>
>
>
>
>
>
>
>



<







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
73
74
75

76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
    pTab->nTabRef++;
  }
  if( sqlite3IndexedByLookup(pParse, pItem) ){
    pTab = 0;
  }
  return pTab;
}

/* Return true if table pTab is read-only.



**



** A table is read-only if any of the following are true:
**
**   1) It is a virtual table and no implementation of the xUpdate method
**      has been provided
**
**   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.


*/
static int tabIsReadOnly(Parse *pParse, Table *pTab){
  sqlite3 *db;
  if( IsVirtual(pTab) ){
    return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0;
  }
  if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0;
  db = pParse->db;
  if( (pTab->tabFlags & TF_Readonly)!=0 ){
    return sqlite3WritableSchema(db)==0 && pParse->nested==0;

  }
  assert( pTab->tabFlags & TF_Shadow );
  return (db->flags & SQLITE_Defensive)!=0
           && db->nVdbeExec==0
           && db->pVtabCtx==0;

}

/*
** 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){
  if( tabIsReadOnly(pParse, pTab) ){
    sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
    return 1;
  }

#ifndef SQLITE_OMIT_VIEW
  if( !viewOk && pTab->pSelect ){
    sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
    return 1;
  }
#endif
  return 0;