]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Ensure the "unique-not-null" flag is set for automatic indexes on columns
authordan <dan@noemail.net>
Mon, 29 Jan 2018 16:22:39 +0000 (16:22 +0000)
committerdan <dan@noemail.net>
Mon, 29 Jan 2018 16:22:39 +0000 (16:22 +0000)
declared with "col UNIQUE NOT NULL" (where the NOT NULL comes after the
UNIQUE).

FossilOrigin-Name: 8767f7b880f2e4112f75f0b6ef7be3f50ab1ae20e103e7d03d8bfe77e6c79438

manifest
manifest.uuid
src/build.c
src/sqliteInt.h
test/notnull.test

index e699a399acb3b56215eaf3eeb046f57b16b19e8e..7a5772a6de9200a642270b6ea241b0bd1d1d7b33 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\smissing\sheader\scomments\sand\sother\scode\sissues\sin\szipfile.c.
-D 2018-01-27T18:55:18.394
+C Ensure\sthe\s"unique-not-null"\sflag\sis\sset\sfor\sautomatic\sindexes\son\scolumns\ndeclared\swith\s"col\sUNIQUE\sNOT\sNULL"\s(where\sthe\sNOT\sNULL\scomes\safter\sthe\nUNIQUE).
+D 2018-01-29T16:22:39.280
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 7a3f714b4fcf793108042b7b0a5c720b0b310ec84314d61ba7f3f49f27e550ea
@@ -432,7 +432,7 @@ F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
 F src/btree.c d711228cac336fb35fff21f3f4a0efe2ad58aa9a800dd02929cdf184be1e78a3
 F src/btree.h 0866c0a08255142ea0e754aabd211c843cab32045c978a592a43152405ed0c84
 F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
-F src/build.c 9f9647454f236cab097f266ae970f899b53c71cadab6756c47e2b2e81392c2a1
+F src/build.c 672022c06e1a5c2653f80c77a687de11f7e65ce81d20fe2825aadfa13a875c33
 F src/callback.c fe677cb5f5abb02f7a772a62a98c2f516426081df68856e8f2d5f950929b966a
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0
@@ -492,7 +492,7 @@ F src/shell.c.in 7cea439c3f7f2e4ed6eb4b3a633cd93dccb1349241400de4da0c1291285ed51
 F src/sqlite.h.in 51f9acf52c80113d793ddd38b3940ad6895d97b4752503b19291fb8fcbf54c5e
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 83a3c4ce93d650bedfd1aa558cb85a516bd6d094445ee989740827d0d944368d
-F src/sqliteInt.h 9c70315598b34810a83e4894455acb18e95cf63ce4e6cbb451ac2d17eabc2544
+F src/sqliteInt.h 119e240796d23054148005524f1d54a61e27dbef53bef3bc7ab65001405f4751
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -1100,7 +1100,7 @@ F test/normalize.test 501630ab49b0b26b65c74124bf03e3374c1b57fa97aae750f848036091
 F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
 F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
-F test/notnull.test f8fcf58669ddba79274daa2770d61dfad8274f62
+F test/notnull.test b6999231221df3534827e45e2005dd7a815fdd5f2c2e1afb9be21ead410816f8
 F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3
 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
 F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823
@@ -1702,7 +1702,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P e63185edfe0c316aa60c1fa085d032425ecc7db54536dfa5a977772eaf3c240e
-R 347b5f95fee3abc6c3f7640c1a70a4d4
+P 6ea8ba312c38365d3e28cfb2a367d729dd2751d1d853843eea0e18126777a320
+R 3ff6b96757835180119359cd3166f741
 U dan
-Z faf05f7eafa9394c044e435efe4a986b
+Z 6c5f0f4d34834e8c6ccf2da8ff3a018a
index 7c9ca14be30fba9c3b870ec90e7ec4920cf4d881..9eae811f9a6d46719837c37bb63b1e8e49fcffb1 100644 (file)
@@ -1 +1 @@
-6ea8ba312c38365d3e28cfb2a367d729dd2751d1d853843eea0e18126777a320
\ No newline at end of file
+8767f7b880f2e4112f75f0b6ef7be3f50ab1ae20e103e7d03d8bfe77e6c79438
\ No newline at end of file
index 58b39d64758d192e9198cffc280ab9e58ef150df..3a656def3e8613f4261a7a49f828db6120e56dbd 100644 (file)
@@ -1118,10 +1118,24 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
 */
 void sqlite3AddNotNull(Parse *pParse, int onError){
   Table *p;
+  Column *pCol;
   p = pParse->pNewTable;
   if( p==0 || NEVER(p->nCol<1) ) return;
-  p->aCol[p->nCol-1].notNull = (u8)onError;
+  pCol = &p->aCol[p->nCol-1];
+  pCol->notNull = (u8)onError;
   p->tabFlags |= TF_HasNotNull;
+
+  /* Set the uniqNotNull flag on any UNIQUE or PK indexes already created
+  ** on this column.  */
+  if( pCol->colFlags & COLFLAG_UNIQUE ){
+    Index *pIdx;
+    for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
+      assert( pIdx->nKeyCol==1 && pIdx->onError!=OE_None );
+      if( pIdx->aiColumn[0]==p->nCol-1 ){
+        pIdx->uniqNotNull = 1;
+      }
+    }
+  }
 }
 
 /*
@@ -3085,7 +3099,9 @@ void sqlite3CreateIndex(
   */
   if( pList==0 ){
     Token prevCol;
-    sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol-1].zName);
+    Column *pCol = &pTab->aCol[pTab->nCol-1];
+    pCol->colFlags |= COLFLAG_UNIQUE;
+    sqlite3TokenInit(&prevCol, pCol->zName);
     pList = sqlite3ExprListAppend(pParse, 0,
               sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
     if( pList==0 ) goto exit_create_index;
index b7b402b8e0eb77ee45eff19b81005efb42d691e0..f408ff62a5debd7af51c09ded948c977aa32a710 100644 (file)
@@ -1754,6 +1754,7 @@ struct Column {
 #define COLFLAG_PRIMKEY  0x0001    /* Column is part of the primary key */
 #define COLFLAG_HIDDEN   0x0002    /* A hidden column in a virtual table */
 #define COLFLAG_HASTYPE  0x0004    /* Type name follows column name */
+#define COLFLAG_UNIQUE   0x0008    /* Column def contains "UNIQUE" or "PK" */
 
 /*
 ** A "Collating Sequence" is defined by an instance of the following
index 23fd33d4bade6ee7c6f200a8c2da9b582cc2668e..32d95eaf24ae9e972ede9e5aaf82b9dc00a073b3 100644 (file)
@@ -561,4 +561,49 @@ do_test notnull-5.5 {
   execsql { SELECT * FROM t1 }
 } {1 2}
 
+#-------------------------------------------------------------------------
+# Check that UNIQUE NOT NULL indexes are always recognized as such.
+#
+proc uses_op_next {sql} {
+  db eval "EXPLAIN $sql" a {
+    if {$a(opcode)=="Next"} { return 1 }
+  }
+  return 0
+}
+
+proc do_uses_op_next_test {tn sql res} {
+  uplevel [list do_test $tn [list uses_op_next $sql] $res]
+}
+
+reset_db
+do_execsql_test notnull-6.0 {
+  CREATE TABLE t1(a UNIQUE);
+  CREATE TABLE t2(a NOT NULL UNIQUE);
+  CREATE TABLE t3(a UNIQUE NOT NULL);
+  CREATE TABLE t4(a NOT NULL);
+  CREATE UNIQUE INDEX t4a ON t4(a);
+
+  CREATE TABLE t5(a PRIMARY KEY);
+  CREATE TABLE t6(a PRIMARY KEY NOT NULL);
+  CREATE TABLE t7(a NOT NULL PRIMARY KEY);
+  CREATE TABLE t8(a PRIMARY KEY) WITHOUT ROWID;
+
+  CREATE TABLE t9(a PRIMARY KEY UNIQUE NOT NULL);
+  CREATE TABLE t10(a UNIQUE PRIMARY KEY NOT NULL);
+}
+
+do_uses_op_next_test notnull-6.1 "SELECT * FROM t1 WHERE a IS ?" 1
+do_uses_op_next_test notnull-6.2 "SELECT * FROM t2 WHERE a IS ?" 0
+do_uses_op_next_test notnull-6.3 "SELECT * FROM t3 WHERE a IS ?" 0
+do_uses_op_next_test notnull-6.4 "SELECT * FROM t4 WHERE a IS ?" 0
+
+do_uses_op_next_test notnull-6.5 "SELECT * FROM t5 WHERE a IS ?" 1
+do_uses_op_next_test notnull-6.6 "SELECT * FROM t6 WHERE a IS ?" 0
+do_uses_op_next_test notnull-6.7 "SELECT * FROM t7 WHERE a IS ?" 0
+do_uses_op_next_test notnull-6.8 "SELECT * FROM t8 WHERE a IS ?" 0
+
+do_uses_op_next_test notnull-6.9 "SELECT * FROM t8 WHERE a IS ?" 0
+do_uses_op_next_test notnull-6.10 "SELECT * FROM t8 WHERE a IS ?" 0
+
 finish_test
+