1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Ensure the "unique-not-null" flag is set for automatic indexes on columns

declared with "col UNIQUE NOT NULL" (where the NOT NULL comes after the
UNIQUE).

FossilOrigin-Name: 8767f7b880f2e4112f75f0b6ef7be3f50ab1ae20e103e7d03d8bfe77e6c79438
This commit is contained in:
dan
2018-01-29 16:22:39 +00:00
parent a07aa8d397
commit 26e731cc88
5 changed files with 73 additions and 11 deletions

View File

@@ -1,5 +1,5 @@
C Fix\smissing\sheader\scomments\sand\sother\scode\sissues\sin\szipfile.c. 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-27T18:55:18.394 D 2018-01-29T16:22:39.280
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in 7a3f714b4fcf793108042b7b0a5c720b0b310ec84314d61ba7f3f49f27e550ea F Makefile.in 7a3f714b4fcf793108042b7b0a5c720b0b310ec84314d61ba7f3f49f27e550ea
@@ -432,7 +432,7 @@ F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
F src/btree.c d711228cac336fb35fff21f3f4a0efe2ad58aa9a800dd02929cdf184be1e78a3 F src/btree.c d711228cac336fb35fff21f3f4a0efe2ad58aa9a800dd02929cdf184be1e78a3
F src/btree.h 0866c0a08255142ea0e754aabd211c843cab32045c978a592a43152405ed0c84 F src/btree.h 0866c0a08255142ea0e754aabd211c843cab32045c978a592a43152405ed0c84
F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96 F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
F src/build.c 9f9647454f236cab097f266ae970f899b53c71cadab6756c47e2b2e81392c2a1 F src/build.c 672022c06e1a5c2653f80c77a687de11f7e65ce81d20fe2825aadfa13a875c33
F src/callback.c fe677cb5f5abb02f7a772a62a98c2f516426081df68856e8f2d5f950929b966a F src/callback.c fe677cb5f5abb02f7a772a62a98c2f516426081df68856e8f2d5f950929b966a
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0 F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0
@@ -492,7 +492,7 @@ F src/shell.c.in 7cea439c3f7f2e4ed6eb4b3a633cd93dccb1349241400de4da0c1291285ed51
F src/sqlite.h.in 51f9acf52c80113d793ddd38b3940ad6895d97b4752503b19291fb8fcbf54c5e F src/sqlite.h.in 51f9acf52c80113d793ddd38b3940ad6895d97b4752503b19291fb8fcbf54c5e
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 83a3c4ce93d650bedfd1aa558cb85a516bd6d094445ee989740827d0d944368d F src/sqlite3ext.h 83a3c4ce93d650bedfd1aa558cb85a516bd6d094445ee989740827d0d944368d
F src/sqliteInt.h 9c70315598b34810a83e4894455acb18e95cf63ce4e6cbb451ac2d17eabc2544 F src/sqliteInt.h 119e240796d23054148005524f1d54a61e27dbef53bef3bc7ab65001405f4751
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35 F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -1100,7 +1100,7 @@ F test/normalize.test 501630ab49b0b26b65c74124bf03e3374c1b57fa97aae750f848036091
F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
F test/notnull.test f8fcf58669ddba79274daa2770d61dfad8274f62 F test/notnull.test b6999231221df3534827e45e2005dd7a815fdd5f2c2e1afb9be21ead410816f8
F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3 F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823 F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823
@@ -1702,7 +1702,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P e63185edfe0c316aa60c1fa085d032425ecc7db54536dfa5a977772eaf3c240e P 6ea8ba312c38365d3e28cfb2a367d729dd2751d1d853843eea0e18126777a320
R 347b5f95fee3abc6c3f7640c1a70a4d4 R 3ff6b96757835180119359cd3166f741
U dan U dan
Z faf05f7eafa9394c044e435efe4a986b Z 6c5f0f4d34834e8c6ccf2da8ff3a018a

View File

@@ -1 +1 @@
6ea8ba312c38365d3e28cfb2a367d729dd2751d1d853843eea0e18126777a320 8767f7b880f2e4112f75f0b6ef7be3f50ab1ae20e103e7d03d8bfe77e6c79438

View File

@@ -1118,10 +1118,24 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
*/ */
void sqlite3AddNotNull(Parse *pParse, int onError){ void sqlite3AddNotNull(Parse *pParse, int onError){
Table *p; Table *p;
Column *pCol;
p = pParse->pNewTable; p = pParse->pNewTable;
if( p==0 || NEVER(p->nCol<1) ) return; 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; 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 ){ if( pList==0 ){
Token prevCol; 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, pList = sqlite3ExprListAppend(pParse, 0,
sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
if( pList==0 ) goto exit_create_index; if( pList==0 ) goto exit_create_index;

View File

@@ -1754,6 +1754,7 @@ struct Column {
#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ #define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */
#define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ #define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */
#define COLFLAG_HASTYPE 0x0004 /* Type name follows column name */ #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 ** A "Collating Sequence" is defined by an instance of the following

View File

@@ -561,4 +561,49 @@ do_test notnull-5.5 {
execsql { SELECT * FROM t1 } execsql { SELECT * FROM t1 }
} {1 2} } {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 finish_test