/ Check-in [5216bfb7]
Login

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

Overview
Comment:Correctly handle an "INTEGER PRIMARY KEY UNIQUE" column in a WITHOUT ROWID table. This is a fix for ticket [bc115541132dad136], a problem discovered by OSSFuzz.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:5216bfb73f1a49bdd879d470de139bf46a212474eaf6f38ad2390536d66a2afd
User & Date: drh 2017-07-30 18:40:52
References
2017-07-31
12:19
Correctly handle an "INTEGER PRIMARY KEY UNIQUE" column in a WITHOUT ROWID table. This is a fix for ticket [bc115541132dad136], cherry-picked from check-in [5216bfb73f1a49bdd8] check-in: 322a2ede user: drh tags: branch-3.19
2017-07-30
20:30
Correctly handle an "INTEGER PRIMARY KEY UNIQUE" column in a WITHOUT ROWID table. This is a fix for ticket [bc115541132dad136] cherry-picked from [5216bfb73f1a49bdd]. check-in: 5c8cb1ff user: drh tags: branch-3.20
Context
2017-07-30
19:50
Add the schema6.test module for demonstrating schemas that generate identical and different content. check-in: ac1da06a user: drh tags: trunk
18:40
Correctly handle an "INTEGER PRIMARY KEY UNIQUE" column in a WITHOUT ROWID table. This is a fix for ticket [bc115541132dad136], a problem discovered by OSSFuzz. check-in: 5216bfb7 user: drh tags: trunk
2017-07-28
22:22
Update Tcl version used by the TclKit batch tool for MSVC. check-in: bcec155e user: mistachkin tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
....
1762
1763
1764
1765
1766
1767
1768









1769
1770
1771
1772
1773
1774
1775
                       SQLITE_IDXTYPE_PRIMARYKEY);
    if( db->mallocFailed ) return;
    pPk = sqlite3PrimaryKeyIndex(pTab);
    pTab->iPKey = -1;
  }else{
    pPk = sqlite3PrimaryKeyIndex(pTab);

    /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
    ** table entry. This is only required if currently generating VDBE
    ** code for a CREATE TABLE (not when parsing one as part of reading
    ** a database schema).  */
    if( v ){
      assert( db->init.busy==0 );
      sqlite3VdbeChangeOpcode(v, pPk->tnum, OP_Goto);
    }

    /*
    ** Remove all redundant columns from the PRIMARY KEY.  For example, change
    ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)".  Later
    ** code assumes the PRIMARY KEY contains no repeated columns.
    */
    for(i=j=1; i<pPk->nKeyCol; i++){
      if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
................................................................................
    }
    pPk->nKeyCol = j;
  }
  assert( pPk!=0 );
  pPk->isCovering = 1;
  if( !db->init.imposterTable ) pPk->uniqNotNull = 1;
  nPk = pPk->nKeyCol;










  /* The root page of the PRIMARY KEY is the table root page */
  pPk->tnum = pTab->tnum;

  /* Update the in-memory representation of all UNIQUE indices by converting
  ** the final rowid column into one or more columns of the PRIMARY KEY.
  */







<
<
<
<
<
<
<
<
<







 







>
>
>
>
>
>
>
>
>







1735
1736
1737
1738
1739
1740
1741









1742
1743
1744
1745
1746
1747
1748
....
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
                       SQLITE_IDXTYPE_PRIMARYKEY);
    if( db->mallocFailed ) return;
    pPk = sqlite3PrimaryKeyIndex(pTab);
    pTab->iPKey = -1;
  }else{
    pPk = sqlite3PrimaryKeyIndex(pTab);










    /*
    ** Remove all redundant columns from the PRIMARY KEY.  For example, change
    ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)".  Later
    ** code assumes the PRIMARY KEY contains no repeated columns.
    */
    for(i=j=1; i<pPk->nKeyCol; i++){
      if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
................................................................................
    }
    pPk->nKeyCol = j;
  }
  assert( pPk!=0 );
  pPk->isCovering = 1;
  if( !db->init.imposterTable ) pPk->uniqNotNull = 1;
  nPk = pPk->nKeyCol;

  /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
  ** table entry. This is only required if currently generating VDBE
  ** code for a CREATE TABLE (not when parsing one as part of reading
  ** a database schema).  */
  if( v && pPk->tnum>0 ){
    assert( db->init.busy==0 );
    sqlite3VdbeChangeOpcode(v, pPk->tnum, OP_Goto);
  }

  /* The root page of the PRIMARY KEY is the table root page */
  pPk->tnum = pTab->tnum;

  /* Update the in-memory representation of all UNIQUE indices by converting
  ** the final rowid column into one or more columns of the PRIMARY KEY.
  */

Changes to test/without_rowid1.test.

323
324
325
326
327
328
329














330
331
332
} {1 {CHECK constraint failed: t70a}}
do_catchsql_test 7.3 {
  CREATE TABLE t70b(
     a INT CHECK( rowid!=33 ),
     b TEXT PRIMARY KEY
  ) WITHOUT ROWID;
} {1 {no such column: rowid}}















  
finish_test







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



323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
} {1 {CHECK constraint failed: t70a}}
do_catchsql_test 7.3 {
  CREATE TABLE t70b(
     a INT CHECK( rowid!=33 ),
     b TEXT PRIMARY KEY
  ) WITHOUT ROWID;
} {1 {no such column: rowid}}

# 2017-07-30: OSSFuzz discovered that an extra entry was being
# added in the sqlite_master table for an "INTEGER PRIMARY KEY UNIQUE"
# WITHOUT ROWID table.  Make sure this has now been fixed.
#
db close
sqlite3 db :memory:
do_execsql_test 8.1 {
  CREATE TABLE t1(x INTEGER PRIMARY KEY UNIQUE, b) WITHOUT ROWID;
  CREATE INDEX t1x ON t1(x);
  INSERT INTO t1(x,b) VALUES('funny','buffalo');
  SELECT type, name, '|' FROM sqlite_master;
} {table t1 | index t1x |}


  
finish_test