/ Check-in [72bf73b2]
Login

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

Overview
Comment:Disallow temporary indices on persistent tables. (CVS 1122)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 72bf73b2c1e3594aa85920e47fc345bba56c80d0
User & Date: drh 2003-11-27 00:48:58
Context
2003-12-04
13:44
Update change log and version in preparation for the 2.8.7 release. (CVS 1123) check-in: 9e79ab6c user: drh tags: trunk
2003-11-27
00:48
Disallow temporary indices on persistent tables. (CVS 1122) check-in: 72bf73b2 user: drh tags: trunk
2003-11-25
23:48
Fix typos in file format documentation. Ticket #505. (CVS 1121) check-in: 4eef9381 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **     PRAGMA
    25     25   **
    26         -** $Id: build.c,v 1.160 2003/09/06 22:18:08 drh Exp $
           26  +** $Id: build.c,v 1.161 2003/11/27 00:48:58 drh Exp $
    27     27   */
    28     28   #include "sqliteInt.h"
    29     29   #include <ctype.h>
    30     30   
    31     31   /*
    32     32   ** This routine is called when a new SQL statement is beginning to
    33     33   ** be parsed.  Check to see if the schema for the database needs
................................................................................
   730    730       zType = pTab->aCol[iCol].zType;
   731    731     }
   732    732     if( pParse->db->file_format>=1 && 
   733    733              zType && sqliteStrICmp(zType, "INTEGER")==0 ){
   734    734       pTab->iPKey = iCol;
   735    735       pTab->keyConf = onError;
   736    736     }else{
   737         -    sqliteCreateIndex(pParse, 0, 0, pList, onError, 0, 0, 0);
          737  +    sqliteCreateIndex(pParse, 0, 0, pList, onError, 0, 0);
   738    738       pList = 0;
   739    739     }
   740    740   
   741    741   primary_key_exit:
   742    742     sqliteIdListDelete(pList);
   743    743     return;
   744    744   }
................................................................................
  1533   1533   */
  1534   1534   void sqliteCreateIndex(
  1535   1535     Parse *pParse,   /* All information about this parse */
  1536   1536     Token *pName,    /* Name of the index.  May be NULL */
  1537   1537     SrcList *pTable, /* Name of the table to index.  Use pParse->pNewTable if 0 */
  1538   1538     IdList *pList,   /* A list of columns to be indexed */
  1539   1539     int onError,     /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  1540         -  int isTemp,      /* True if this is a temporary index */
  1541   1540     Token *pStart,   /* The CREATE token that begins a CREATE TABLE statement */
  1542   1541     Token *pEnd      /* The ")" that closes the CREATE INDEX statement */
  1543   1542   ){
  1544   1543     Table *pTab;     /* Table to be indexed */
  1545   1544     Index *pIndex;   /* The index to be created */
  1546   1545     char *zName = 0;
  1547   1546     int i, j;
  1548   1547     Token nullId;    /* Fake token for an empty ID list */
  1549   1548     DbFixer sFix;    /* For assigning database names to pTable */
         1549  +  int isTemp;      /* True for a temporary index */
  1550   1550     sqlite *db = pParse->db;
  1551   1551   
  1552   1552     if( pParse->nErr || sqlite_malloc_failed ) goto exit_create_index;
  1553         -  if( !isTemp && pParse->initFlag 
         1553  +  if( pParse->initFlag 
  1554   1554        && sqliteFixInit(&sFix, pParse, pParse->iDb, "index", pName)
  1555   1555        && sqliteFixSrcList(&sFix, pTable)
  1556   1556     ){
  1557   1557       goto exit_create_index;
  1558   1558     }
  1559   1559   
  1560   1560     /*
................................................................................
  1571   1571     if( pTab==0 || pParse->nErr ) goto exit_create_index;
  1572   1572     if( pTab->readOnly ){
  1573   1573       sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
  1574   1574         " may not be indexed", 0);
  1575   1575       pParse->nErr++;
  1576   1576       goto exit_create_index;
  1577   1577     }
  1578         -  if( !isTemp && pTab->iDb>=2 && pParse->initFlag==0 ){
         1578  +  if( pTab->iDb>=2 && pParse->initFlag==0 ){
  1579   1579       sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, 
  1580         -      " may not have non-temporary indices added", 0);
         1580  +      " may not have indices added", 0);
  1581   1581       pParse->nErr++;
  1582   1582       goto exit_create_index;
  1583   1583     }
  1584   1584     if( pTab->pSelect ){
  1585   1585       sqliteSetString(&pParse->zErrMsg, "views may not be indexed", 0);
  1586   1586       pParse->nErr++;
  1587   1587       goto exit_create_index;
  1588   1588     }
  1589         -  if( pTab->iDb==1 ){
  1590         -    isTemp = 1;
  1591         -  }
         1589  +  isTemp = pTab->iDb==1;
  1592   1590   
  1593   1591     /*
  1594   1592     ** Find the name of the index.  Make sure there is not already another
  1595   1593     ** index or table with the same name.  
  1596   1594     **
  1597   1595     ** Exception:  If we are reading the names of permanent indices from the
  1598   1596     ** sqlite_master table (because some other process changed the schema) and
................................................................................
  1635   1633   
  1636   1634     /* Check for authorization to create an index.
  1637   1635     */
  1638   1636   #ifndef SQLITE_OMIT_AUTHORIZATION
  1639   1637     {
  1640   1638       const char *zDb = db->aDb[pTab->iDb].zName;
  1641   1639   
  1642         -    assert( isTemp==0 || isTemp==1 );
  1643         -    assert( pTab->iDb==pParse->iDb || isTemp==1 );
         1640  +    assert( pTab->iDb==pParse->iDb || isTemp );
  1644   1641       if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
  1645   1642         goto exit_create_index;
  1646   1643       }
  1647   1644       i = SQLITE_CREATE_INDEX;
  1648   1645       if( isTemp ) i = SQLITE_CREATE_TEMP_INDEX;
  1649   1646       if( sqliteAuthCheck(pParse, i, zName, pTab->zName, zDb) ){
  1650   1647         goto exit_create_index;

Changes to src/parse.y.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains SQLite's grammar for SQL.  Process this file
    13     13   ** using the lemon parser generator to generate C code that runs
    14     14   ** the parser.  Lemon will also generate a header file containing
    15     15   ** numeric codes for all of the tokens.
    16     16   **
    17         -** @(#) $Id: parse.y,v 1.103 2003/09/30 01:54:14 drh Exp $
           17  +** @(#) $Id: parse.y,v 1.104 2003/11/27 00:48:58 drh Exp $
    18     18   */
    19     19   %token_prefix TK_
    20     20   %token_type {Token}
    21     21   %default_type {Token}
    22     22   %extra_argument {Parse *pParse}
    23     23   %syntax_error {
    24     24     if( pParse->zErrMsg==0 ){
................................................................................
   173    173   
   174    174   // In addition to the type name, we also care about the primary key and
   175    175   // UNIQUE constraints.
   176    176   //
   177    177   ccons ::= NULL onconf.
   178    178   ccons ::= NOT NULL onconf(R).               {sqliteAddNotNull(pParse, R);}
   179    179   ccons ::= PRIMARY KEY sortorder onconf(R).  {sqliteAddPrimaryKey(pParse,0,R);}
   180         -ccons ::= UNIQUE onconf(R).           {sqliteCreateIndex(pParse,0,0,0,R,0,0,0);}
          180  +ccons ::= UNIQUE onconf(R).           {sqliteCreateIndex(pParse,0,0,0,R,0,0);}
   181    181   ccons ::= CHECK LP expr RP onconf.
   182    182   ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R).
   183    183                                   {sqliteCreateForeignKey(pParse,0,&T,TA,R);}
   184    184   ccons ::= defer_subclause(D).   {sqliteDeferForeignKey(pParse,D);}
   185    185   ccons ::= COLLATE id(C).  {
   186    186      sqliteAddCollateType(pParse, sqliteCollateType(C.z, C.n));
   187    187   }
................................................................................
   220    220   conslist ::= conslist COMMA tcons.
   221    221   conslist ::= conslist tcons.
   222    222   conslist ::= tcons.
   223    223   tcons ::= CONSTRAINT nm.
   224    224   tcons ::= PRIMARY KEY LP idxlist(X) RP onconf(R).
   225    225                                                {sqliteAddPrimaryKey(pParse,X,R);}
   226    226   tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
   227         -                                     {sqliteCreateIndex(pParse,0,0,X,R,0,0,0);}
          227  +                                       {sqliteCreateIndex(pParse,0,0,X,R,0,0);}
   228    228   tcons ::= CHECK expr onconf.
   229    229   tcons ::= FOREIGN KEY LP idxlist(FA) RP
   230    230             REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). {
   231    231       sqliteCreateForeignKey(pParse, FA, &T, TA, R);
   232    232       sqliteDeferForeignKey(pParse, D);
   233    233   }
   234    234   %type defer_subclause_opt {int}
................................................................................
   697    697      {A = sqliteExprListAppend(X,Y,0);}
   698    698   exprlist(A) ::= expritem(X).            {A = sqliteExprListAppend(0,X,0);}
   699    699   expritem(A) ::= expr(X).                {A = X;}
   700    700   expritem(A) ::= .                       {A = 0;}
   701    701   
   702    702   ///////////////////////////// The CREATE INDEX command ///////////////////////
   703    703   //
   704         -cmd ::= CREATE(S) temp(T) uniqueflag(U) INDEX nm(X)
          704  +cmd ::= CREATE(S) uniqueflag(U) INDEX nm(X)
   705    705           ON nm(Y) dbnm(D) LP idxlist(Z) RP(E) onconf(R). {
   706    706     SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
   707    707     if( U!=OE_None ) U = R;
   708    708     if( U==OE_Default) U = OE_Abort;
   709         -  sqliteCreateIndex(pParse, &X, pSrc, Z, U, T, &S, &E);
          709  +  sqliteCreateIndex(pParse, &X, pSrc, Z, U, &S, &E);
   710    710   }
   711    711   
   712    712   %type uniqueflag {int}
   713    713   uniqueflag(A) ::= UNIQUE.  { A = OE_Abort; }
   714    714   uniqueflag(A) ::= .        { A = OE_None; }
   715    715   
   716    716   %type idxlist {IdList*}

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.202 2003/11/11 23:30:36 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.203 2003/11/27 00:48:58 drh Exp $
    15     15   */
    16     16   #include "config.h"
    17     17   #include "sqlite.h"
    18     18   #include "hash.h"
    19     19   #include "vdbe.h"
    20     20   #include "parse.h"
    21     21   #include "btree.h"
................................................................................
  1097   1097   IdList *sqliteIdListAppend(IdList*, Token*);
  1098   1098   int sqliteIdListIndex(IdList*,const char*);
  1099   1099   SrcList *sqliteSrcListAppend(SrcList*, Token*, Token*);
  1100   1100   void sqliteSrcListAddAlias(SrcList*, Token*);
  1101   1101   void sqliteSrcListAssignCursors(Parse*, SrcList*);
  1102   1102   void sqliteIdListDelete(IdList*);
  1103   1103   void sqliteSrcListDelete(SrcList*);
  1104         -void sqliteCreateIndex(Parse*,Token*,SrcList*,IdList*,int,int,Token*,Token*);
         1104  +void sqliteCreateIndex(Parse*,Token*,SrcList*,IdList*,int,Token*,Token*);
  1105   1105   void sqliteDropIndex(Parse*, SrcList*);
  1106   1106   void sqliteAddKeyType(Vdbe*, ExprList*);
  1107   1107   void sqliteAddIdxKeyType(Vdbe*, Index*);
  1108   1108   int sqliteSelect(Parse*, Select*, int, int, Select*, int, int*);
  1109   1109   Select *sqliteSelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
  1110   1110                           int,int,int);
  1111   1111   void sqliteSelectDelete(Select*);

Changes to test/auth.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script is testing the ATTACH and DETACH commands
    13     13   # and related functionality.
    14     14   #
    15         -# $Id: auth.test,v 1.10 2003/06/06 19:00:42 drh Exp $
           15  +# $Id: auth.test,v 1.11 2003/11/27 00:49:23 drh Exp $
    16     16   #
    17     17   
    18     18   set testdir [file dirname $argv0]
    19     19   source $testdir/tester.tcl
    20     20   
    21     21   # disable this test if the SQLITE_OMIT_AUTHORIZATION macro is
    22     22   # defined during compilation.
................................................................................
   263    263     }
   264    264     catchsql {INSERT INTO t2 VALUES(1,2,3)}
   265    265   } {0 {}}
   266    266   do_test auth-1.34 {
   267    267     execsql {SELECT * FROM t2}
   268    268   } {1 2 3}
   269    269   
   270         -do_test auth-1.35 {
          270  +do_test auth-1.35.1 {
   271    271     proc auth {code arg1 arg2 arg3 arg4} {
   272    272       if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="b"} {
   273    273         return SQLITE_DENY
   274    274       }
   275    275       return SQLITE_OK
   276    276     }
   277    277     catchsql {SELECT * FROM t2}
   278    278   } {1 {access to t2.b is prohibited}}
          279  +do_test auth-1.35.2 {
          280  +  execsql {ATTACH DATABASE 'test.db' AS two}
          281  +  catchsql {SELECT * FROM two.t2}
          282  +} {1 {access to two.t2.b is prohibited}}
          283  +execsql {DETACH DATABASE two}
   279    284   do_test auth-1.36 {
   280    285     proc auth {code arg1 arg2 arg3 arg4} {
   281    286       if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="b"} {
   282    287         return SQLITE_IGNORE
   283    288       }
   284    289       return SQLITE_OK
   285    290     }

Changes to test/trigger2.test.

    56     56   	{CREATE TEMP TABLE tbl (a, b);} 
    57     57   	{CREATE TABLE tbl (a, b);} 
    58     58   	{CREATE TABLE tbl (a INTEGER PRIMARY KEY, b);} 
    59     59   	{CREATE TEMPORARY TABLE tbl (a INTEGER PRIMARY KEY, b);} 
    60     60           {CREATE TABLE tbl (a, b PRIMARY KEY);} 
    61     61   	{CREATE TABLE tbl (a, b); CREATE INDEX tbl_idx ON tbl(b);} 
    62     62   	{CREATE TEMP TABLE tbl (a, b); CREATE INDEX tbl_idx ON tbl(b);} 
    63         -	{CREATE TABLE tbl (a, b); CREATE TEMP INDEX tbl_idx ON tbl(b);} 
    64     63   } {
    65     64     incr ii
    66     65     catchsql { DROP INDEX tbl_idx; }
    67     66     catchsql {
    68     67       DROP TABLE rlog;
    69     68       DROP TABLE clog;
    70     69       DROP TABLE tbl;