SQLite

Check-in [786b5991dc]
Login

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

Overview
Comment:Ensure that it is not possible to rename columns of system tables, views or virtual tables.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | alter-table-rename-column
Files: files | file ages | folders
SHA3-256: 786b5991dc0bb6ba13327a3ac9d04efbf8b591dedc736b719b206ffd865b1918
User & Date: dan 2018-08-20 16:16:05.616
Context
2018-08-20
20:01
Add further tests for RENAME COLUMN. (check-in: 82c4c10a96 user: dan tags: alter-table-rename-column)
16:16
Ensure that it is not possible to rename columns of system tables, views or virtual tables. (check-in: 786b5991dc user: dan tags: alter-table-rename-column)
2018-08-18
18:27
Additional fixes for harmless compiler warnings that are specific to this branch. (check-in: 9d8e73bf71 user: drh tags: alter-table-rename-column)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/alter.c.
786
787
788
789
790
791
792

































793
794
795
796
797
798
799
  sqlite3ChangeCookie(pParse, iDb);

exit_begin_add_column:
  sqlite3SrcListDelete(db, pSrc);
  return;
}


































/*
** Handles the following parser reduction:
**
**  cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew
*/
void sqlite3AlterRenameColumn(
  Parse *pParse,                  /* Parsing context */







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







786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
  sqlite3ChangeCookie(pParse, iDb);

exit_begin_add_column:
  sqlite3SrcListDelete(db, pSrc);
  return;
}

/*
** Parameter pTab is the subject of an ALTER TABLE ... RENAME COLUMN
** command. This function checks if the table is a view or virtual
** table (columns of views or virtual tables may not be renamed). If so,
** it loads an error message into pParse and returns non-zero.
**
** Or, if pTab is not a view or virtual table, zero is returned.
*/
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
static int isRealTable(Parse *pParse, Table *pTab){
  const char *zType = 0;
#ifndef SQLITE_OMIT_VIEW
  if( pTab->pSelect ){
    zType = "view";
  }else 
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( IsVirtual(pTab) ){
    zType = "virtual table";
  }
#endif
  if( zType ){
    sqlite3ErrorMsg(
        pParse, "columns of %s %s may not be renamed", zType, pTab->zName
    );
    return 1;
  }
  return 0;
}
#else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */
# define isRealTable(x,y) (0)
#endif

/*
** Handles the following parser reduction:
**
**  cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew
*/
void sqlite3AlterRenameColumn(
  Parse *pParse,                  /* Parsing context */
812
813
814
815
816
817
818

819
820
821
822
823
824
825

  /* Locate the table to be altered */
  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
  if( !pTab ) goto exit_rename_column;

  /* Cannot alter a system table */
  if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column;


  /* Which schema holds the table to be altered */  
  iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iSchema>=0 );
  zDb = db->aDb[iSchema].zDbSName;

  /* Make sure the old name really is a column name in the table to be







>







845
846
847
848
849
850
851
852
853
854
855
856
857
858
859

  /* Locate the table to be altered */
  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
  if( !pTab ) goto exit_rename_column;

  /* Cannot alter a system table */
  if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column;
  if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column;

  /* Which schema holds the table to be altered */  
  iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iSchema>=0 );
  zDb = db->aDb[iSchema].zDbSName;

  /* Make sure the old name really is a column name in the table to be
Changes to test/altercol.test.
461
462
463
464
465
466
467
468









































469

do_execsql_test 11.2 {
  CREATE VIEW v1 AS SELECT e1.*, x1.c FROM e1, x1;
}

do_catchsql_test 11.3 {
  ALTER TABLE x1 RENAME c TO ccc;
} {1 {error processing view v1: no such module: echo}}










































finish_test









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

>
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
do_execsql_test 11.2 {
  CREATE VIEW v1 AS SELECT e1.*, x1.c FROM e1, x1;
}

do_catchsql_test 11.3 {
  ALTER TABLE x1 RENAME c TO ccc;
} {1 {error processing view v1: no such module: echo}}

#-------------------------------------------------------------------------
# Test some error conditions:
#
#   1. Renaming a column of a system table,
#   2. Renaming a column of a VIEW,
#   3. Renaming a column of a virtual table.
#
reset_db
do_execsql_test 12.1.1 {
  CREATE TABLE t1(a, b);
  CREATE INDEX t1a ON t1(a);
  INSERT INTO t1 VALUES(1, 1), (2, 2), (3, 4);
  ANALYZE;
}
do_catchsql_test 12.1.2 {
  ALTER TABLE sqlite_stat1 RENAME idx TO theindex;
} {1 {table sqlite_stat1 may not be altered}}
do_execsql_test 12.1.3 {
  SELECT sql FROM sqlite_master WHERE tbl_name = 'sqlite_stat1'
} {{CREATE TABLE sqlite_stat1(tbl,idx,stat)}}

do_execsql_test 12.2.1 {
  CREATE VIEW v1 AS SELECT * FROM t1;
  CREATE VIEW v2(c, d) AS SELECT * FROM t1;
}
do_catchsql_test 12.2.2 {
  ALTER TABLE v1 RENAME a TO z;
} {1 {columns of view v1 may not be renamed}}
do_catchsql_test 12.2.3 {
  ALTER TABLE v2 RENAME c TO y;
} {1 {columns of view v2 may not be renamed}}

ifcapable fts5 {
  do_execsql_test 12.3.1 {
    CREATE VIRTUAL TABLE ft USING fts5(a, b, c);
  }
  do_catchsql_test 12.2.2 {
    ALTER TABLE ft RENAME a TO z;
  } {1 {columns of virtual table ft may not be renamed}}
}

finish_test