/ Check-in [0a988ce3]
Login

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

Overview
Comment:Do not allow shadow tables to be dropped in defensive mode.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | apple-osx
Files: files | file ages | folders
SHA3-256: 0a988ce3405f2fdfe8d80db2893bf675a41ba6ef5c6e29f6a80cfc307d83bfab
User & Date: drh 2019-11-16 18:36:12
Context
2019-11-16
18:36
Do not allow shadow tables to be dropped in defensive mode. Leaf check-in: 0a988ce3 user: drh tags: apple-osx
18:30
Modify three test cases so that they work even with unusual versions of the library printf(). check-in: c2528907 user: drh tags: apple-osx
12:04
Do not allow shadow tables to be dropped in defensive mode. check-in: 70390bbc user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

2741
2742
2743
2744
2745
2746
2747
















2748
2749
2750
2751
2752
2753
2754
....
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
    sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
    sqlite3MayAbort(pParse);
  }
  sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
  sqlite3ChangeCookie(pParse, iDb);
  sqliteViewResetAll(db, iDb);
}

















/*
** This routine is called to do the work of a DROP TABLE statement.
** pName is the name of the table to be dropped.
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
  Table *pTab;
................................................................................
      goto exit_drop_table;
    }
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
      goto exit_drop_table;
    }
  }
#endif
  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 
    && sqlite3StrNICmp(pTab->zName+7, "stat", 4)!=0
    && sqlite3StrNICmp(pTab->zName+7, "parameters", 10)!=0 ){
    sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
    goto exit_drop_table;
  }

#ifndef SQLITE_OMIT_VIEW
  /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
  ** on a table.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
<
<







2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
....
2827
2828
2829
2830
2831
2832
2833
2834


2835
2836
2837
2838
2839
2840
2841
    sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
    sqlite3MayAbort(pParse);
  }
  sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
  sqlite3ChangeCookie(pParse, iDb);
  sqliteViewResetAll(db, iDb);
}

/*
** Return true if it is not allowed to drop the given table
*/
static int tableMayNotBeDropped(Parse *pParse, Table *pTab){
  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
    if( sqlite3StrNICmp(pTab->zName+7, "stat", 4)==0 ) return 0;
    if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0;
    return 1;
  }
  if( pTab->tabFlags & TF_Shadow ){
    sqlite3 *db = pParse->db;
    if( (db->flags & SQLITE_Defensive)!=0 && db->nVdbeExec==0 ) return 1;
  }
  return 0;
}

/*
** This routine is called to do the work of a DROP TABLE statement.
** pName is the name of the table to be dropped.
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
  Table *pTab;
................................................................................
      goto exit_drop_table;
    }
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
      goto exit_drop_table;
    }
  }
#endif
  if( tableMayNotBeDropped(pParse, pTab) ){


    sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
    goto exit_drop_table;
  }

#ifndef SQLITE_OMIT_VIEW
  /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
  ** on a table.

Changes to test/altertab.test.

538
539
540
541
542
543
544
545
546
547
548
549
550
551
552




553
554
555
556
557
558
559
560
561
562
563
564

  sqlite3_db_config db DEFENSIVE 1

  do_execsql_test 16.0 {
    CREATE VIRTUAL TABLE y1 USING fts3;
  }

  do_catchsql_test 16.1 {
    INSERT INTO y1_segments VALUES(1, X'1234567890');
  } {1 {table y1_segments may not be modified}}

  do_catchsql_test 16.2 {
    ALTER TABLE y1_segments RENAME TO abc;
  } {1 {table y1_segments may not be altered}}





  do_execsql_test 16.3 {
    ALTER TABLE y1 RENAME TO z1;
  }

  do_execsql_test 16.4 {
    SELECT * FROM z1_segments;
  }
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 17.0 {







|



|



>
>
>
>
|



|







538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568

  sqlite3_db_config db DEFENSIVE 1

  do_execsql_test 16.0 {
    CREATE VIRTUAL TABLE y1 USING fts3;
  }

  do_catchsql_test 16.10 {
    INSERT INTO y1_segments VALUES(1, X'1234567890');
  } {1 {table y1_segments may not be modified}}

  do_catchsql_test 16.20 {
    ALTER TABLE y1_segments RENAME TO abc;
  } {1 {table y1_segments may not be altered}}

  do_catchsql_test 16.21 {
    DROP TABLE y1_segments;
  } {1 {table y1_segments may not be dropped}}

  do_execsql_test 16.30 {
    ALTER TABLE y1 RENAME TO z1;
  }

  do_execsql_test 16.40 {
    SELECT * FROM z1_segments;
  }
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 17.0 {