1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

Merge latest trunk changes with this branch.

FossilOrigin-Name: d693be375380fbfca426999a77eeecb8453fa77b77f608bfe266945dee1da41d
This commit is contained in:
dan
2019-12-28 08:33:46 +00:00
7 changed files with 210 additions and 83 deletions

View File

@@ -1,5 +1,5 @@
C Fix\san\sassert()\sfailure\sin\saltertable3-22.4.
D 2019-12-28T08:26:47.067
C Merge\slatest\strunk\schanges\swith\sthis\sbranch.
D 2019-12-28T08:33:46.892
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -480,7 +480,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041
F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
F src/dbstat.c 6c407e549406c10fde9ac3987f6d734459205239ad370369bc5fcd683084a4fa
F src/delete.c a5c59b9c0251cf7682bc52af0d64f09b1aefc6781a63592c8f1136f7b73c66e4
F src/expr.c 188a8c039c95a0b4adb6c9dcde7252810c90e5145333634b924cbe348b187df8
F src/expr.c de4fa05000145cbb6ff29b106e2c7dded5fe3d7882c518b2bc6f63c27891a645
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 92a248ec0fa4ed8ab60c98d9b188ce173aaf218f32e7737ba77deb2a684f9847
F src/func.c ed33e38cd642058182a31a3f518f2e34f4bbe53aa483335705c153c4d3e50b12
@@ -489,7 +489,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 831408b14a146e93a4e02ddba54dcdfd8097463b9c00ca2ed9daed790c5d452a
F src/insert.c be02cb3503277063879f9c04ce2feb9ffdcdd8f6abd975cc6007f745392b495b
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c d74f5e7bd51f3c9d283442473eb65aef359664efd6513591c03f01881c4ae2da
F src/main.c 868ae7db7a54fe859bf2ca8b7a4f24e9fa03a6134abfb7c9801d08411ef5dacb
@@ -600,7 +600,7 @@ F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78
F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507
F src/util.c 2c92bc706bbdb1c45a25180291e7e05a56e297aa5dd7b2bcd2b1c47e8bb05b17
F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf
F src/vdbe.c 8b0f3445b75be6aa381a961a3206decf6e169c5b5625349fcb7e287e9deffa14
F src/vdbe.c 4d91d635d7aff34e09fade185911c7980fc42f93cc7b18f5387fad5a1166f08c
F src/vdbe.h 3f068f00b23aebf392df142312ab5874588371c6d83e60d953f6d6b6453491c5
F src/vdbeInt.h 1ccaf470287e2d153b16cf7b0274d436db2c2f74cdf14afd1a0ff4cb51548ae6
F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02
@@ -614,7 +614,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 15a2845769f51ba132f9cf0b2c7a6887a91fc8437892dbcce9fcdc68b66d60a1
F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d
F src/where.c 58653781a4b31fa16b95b953591fdc1f1ed5ff77574e59b90a27da3819b60a46
F src/where.c 2796f052b577e0c28d9e05e7fcbe30917af4a1263117b36a49d99feb01d5e851
F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217
F src/wherecode.c d42d3e0fe93786621b84dec8065e1dc6b324d7c5934df52f141555843b6aef4e
F src/whereexpr.c 4b34be1434183e7bb8a05d4bf42bd53ea53021b0b060936fbd12062b4ff6b396
@@ -1023,7 +1023,7 @@ F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c
F test/gencol1.test 66b361e39820e28b1be1a50de275d14f5a448c0cbcb71b6d38eedb683391cee4
F test/gencol1.test e89eafdf03245e2609ddf6e9b0add37a17ce229095836c409131764c3a5282a5
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
F test/having.test e4098a4b8962f9596035c3b87a8928a10648acc509f1bb8d6f96413bbf79a1b3
F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751
@@ -1853,7 +1853,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 d29edef93451cc67a5d69c1cce1b1832d9ca8fff1f600afdd51338b74d077b92
R cba70c36e93dfffeaca2b813bf7688d4
P c566a91d5c4290b0a491a01e85bf8f9fbebf2910e0d478bafc2d22da7f749cae 0d743585c242ebd898b232f42937a2306752aaed0a6756705e3ef1cf7593aa97
R 9a4f1ab6b8173f2c45a1b04ce638436e
U dan
Z cffa8180beb2f61f82cbe2ab0339d09f
Z 162aa692a1101b20f72fbada0fcb5043

View File

@@ -1 +1 @@
c566a91d5c4290b0a491a01e85bf8f9fbebf2910e0d478bafc2d22da7f749cae
d693be375380fbfca426999a77eeecb8453fa77b77f608bfe266945dee1da41d

View File

@@ -2292,7 +2292,7 @@ static Select *isCandidateForInOpt(Expr *pX){
testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
return 0; /* No DISTINCT keyword and no aggregate functions */
}
assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */
if( p->pGroupBy ) return 0; /* Has no GROUP BY clause */
if( p->pLimit ) return 0; /* Has no LIMIT clause */
if( p->pWhere ) return 0; /* Has no WHERE clause */
pSrc = p->pSrc;

View File

@@ -1020,6 +1020,7 @@ void sqlite3Insert(
** goto C
** D: ...
*/
sqlite3VdbeReleaseRegisters(pParse, regData, pTab->nCol, 0);
addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
VdbeCoverage(v);
if( ipkColumn>=0 ){
@@ -1280,6 +1281,15 @@ void sqlite3Insert(
sqlite3VdbeAddOp1(v, OP_Close, srcTab);
}else if( pSelect ){
sqlite3VdbeGoto(v, addrCont);
#ifdef SQLITE_DEBUG
/* If we are jumping back to an OP_Yield that is preceded by an
** OP_ReleaseReg, set the p5 flag on the OP_Goto so that the
** OP_ReleaseReg will be included in the loop. */
if( sqlite3VdbeGetOp(v, addrCont-1)->opcode==OP_ReleaseReg ){
assert( sqlite3VdbeGetOp(v, addrCont)->opcode==OP_Yield );
sqlite3VdbeChangeP5(v, 1);
}
#endif
sqlite3VdbeJumpHere(v, addrInsTop);
}
@@ -1502,7 +1512,6 @@ void sqlite3GenerateConstraintChecks(
int ix; /* Index loop counter */
int nCol; /* Number of columns */
int onError; /* Conflict resolution strategy */
int addr1; /* Address of jump instruction */
int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
Index *pUpIdx = 0; /* Index to which to apply the upsert */
@@ -1546,15 +1555,26 @@ void sqlite3GenerateConstraintChecks(
/* Test all NOT NULL constraints.
*/
if( pTab->tabFlags & TF_HasNotNull ){
int b2ndPass = 0; /* True if currently running 2nd pass */
int nSeenReplace = 0; /* Number of ON CONFLICT REPLACE operations */
int nGenerated = 0; /* Number of generated columns with NOT NULL */
while(1){ /* Make 2 passes over columns. Exit loop via "break" */
for(i=0; i<nCol; i++){
int iReg;
onError = pTab->aCol[i].notNull;
int iReg; /* Register holding column value */
Column *pCol = &pTab->aCol[i]; /* The column to check for NOT NULL */
int isGenerated; /* non-zero if column is generated */
onError = pCol->notNull;
if( onError==OE_None ) continue; /* No NOT NULL on this column */
if( i==pTab->iPKey ){
continue; /* ROWID is never NULL */
}
if( aiChng && aiChng[i]<0 ){
/* Don't bother checking for NOT NULL on columns that do not change */
isGenerated = pCol->colFlags & COLFLAG_GENERATED;
if( isGenerated && !b2ndPass ){
nGenerated++;
continue; /* Generated columns processed on 2nd pass */
}
if( aiChng && aiChng[i]<0 && !isGenerated ){
/* Do not check NOT NULL on columns that do not change */
continue;
}
if( overrideError!=OE_Default ){
@@ -1562,30 +1582,33 @@ void sqlite3GenerateConstraintChecks(
}else if( onError==OE_Default ){
onError = OE_Abort;
}
if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
if( onError==OE_Replace ){
if( b2ndPass /* REPLACE becomes ABORT on the 2nd pass */
|| pCol->pDflt==0 /* REPLACE is ABORT if no DEFAULT value */
){
testcase( pCol->colFlags & COLFLAG_VIRTUAL );
testcase( pCol->colFlags & COLFLAG_STORED );
testcase( pCol->colFlags & COLFLAG_GENERATED );
onError = OE_Abort;
}else{
assert( !isGenerated );
}
}else if( b2ndPass && !isGenerated ){
continue;
}
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
|| onError==OE_Ignore || onError==OE_Replace );
addr1 = 0;
testcase( i!=sqlite3TableColumnToStorage(pTab, i) );
testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL );
testcase( pTab->aCol[i].colFlags & COLFLAG_STORED );
iReg = sqlite3TableColumnToStorage(pTab, i) + regNewData + 1;
switch( onError ){
case OE_Replace: {
assert( onError==OE_Replace );
addr1 = sqlite3VdbeMakeLabel(pParse);
sqlite3VdbeAddOp2(v, OP_NotNull, iReg, addr1);
int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, iReg);
VdbeCoverage(v);
if( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 ){
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
sqlite3VdbeAddOp2(v, OP_NotNull, iReg, addr1);
VdbeCoverage(v);
}
onError = OE_Abort;
/* Fall through into the OE_Abort case to generate code that runs
** if both the input and the default value are NULL */
assert( (pCol->colFlags & COLFLAG_GENERATED)==0 );
nSeenReplace++;
sqlite3ExprCode(pParse, pCol->pDflt, iReg);
sqlite3VdbeJumpHere(v, addr1);
break;
}
case OE_Abort:
sqlite3MayAbort(pParse);
@@ -1593,13 +1616,12 @@ void sqlite3GenerateConstraintChecks(
case OE_Rollback:
case OE_Fail: {
char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
pTab->aCol[i].zName);
pCol->zName);
sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL,
onError, iReg);
sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
VdbeCoverage(v);
if( addr1 ) sqlite3VdbeResolveLabel(v, addr1);
break;
}
default: {
@@ -1608,9 +1630,25 @@ void sqlite3GenerateConstraintChecks(
VdbeCoverage(v);
break;
}
} /* end switch(onError) */
} /* end loop i over columns */
if( nGenerated==0 && nSeenReplace==0 ){
/* If there are no generated columns with NOT NULL constraints
** and no NOT NULL ON CONFLICT REPLACE constraints, then a single
** pass is sufficient */
break;
}
if( b2ndPass ) break; /* Never need more than 2 passes */
b2ndPass = 1;
if( nSeenReplace>0 && (pTab->tabFlags & TF_HasGenerated)!=0 ){
/* If any NOT NULL ON CONFLICT REPLACE constraints fired on the
** first pass, recomputed values for all generated columns, as
** those values might depend on columns affected by the REPLACE.
*/
sqlite3ComputeGeneratedColumns(pParse, regNewData+1, pTab);
}
}
} /* end of 2-pass loop */
} /* end if( has-not-null-constraints ) */
/* Test all CHECK constraints
*/

View File

@@ -845,6 +845,20 @@ int sqlite3VdbeExec(
** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: { /* jump */
#ifdef SQLITE_DEBUG
/* In debuggging mode, when the p5 flags is set on an OP_Goto, that
** means we should really jump back to the preceeding OP_ReleaseReg
** instruction. */
if( pOp->p5 ){
assert( pOp->p2 < (int)(pOp - aOp) );
assert( pOp->p2 > 1 );
pOp = &aOp[pOp->p2 - 2];
assert( pOp[1].opcode==OP_ReleaseReg );
goto check_for_interrupt;
}
#endif
jump_to_p2_and_check_for_interrupt:
pOp = &aOp[pOp->p2 - 1];

View File

@@ -870,8 +870,8 @@ static void constructAutomaticIndex(
pTabItem->fg.viaCoroutine = 0;
}else{
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
}
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
}
sqlite3VdbeJumpHere(v, addrTop);
sqlite3ReleaseTempReg(pParse, regRecord);
@@ -3502,7 +3502,8 @@ static int whereLoopAddOr(
if( rc==SQLITE_OK ){
rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable);
}
assert( rc==SQLITE_OK || sCur.n==0 );
assert( rc==SQLITE_OK || rc==SQLITE_DONE || sCur.n==0 );
testcase( rc==SQLITE_DONE );
if( sCur.n==0 ){
sSum.n = 0;
break;

View File

@@ -211,16 +211,81 @@ do_catchsql_test gencol1-6.10 {
REPLACE INTO t0(c1) VALUES(NULL);
} {1 {NOT NULL constraint failed: t0.c0}}
# 2019-11-06 ticket b13b7dce76e9352b34e7
# 2019-11-06 ticket https://www.sqlite.org/src/info/2399f5986134f79c
# 2019-12-27 ticket https://www.sqlite.org/src/info/5fbc159eeb092130
# 2019-12-27 ticket https://www.sqlite.org/src/info/37823501c68a09f9
#
# All of the above tickets deal with NOT NULL ON CONFLICT REPLACE
# constraints on tables that have generated columns.
#
reset_db
do_execsql_test gencol1-7.10 {
DROP TABLE IF EXISTS t0;
CREATE TABLE t0 (c0 GENERATED ALWAYS AS (1), c1 UNIQUE, c2 UNIQUE);
INSERT INTO t0(c1) VALUES (1);
SELECT quote(0 = t0.c2 OR t0.c1 BETWEEN t0.c2 AND 1) FROM t0;
} {NULL}
do_execsql_test gencol1-7.11 {
DROP TABLE t0;
CREATE TABLE t0(c0 NOT NULL DEFAULT 'xyz', c1 AS(c0) NOT NULL);
REPLACE INTO t0(c0) VALUES(NULL);
SELECT * FROM t0;
} {xyz xyz}
do_execsql_test gencol1-7.12 {
DROP TABLE t0;
CREATE TABLE t0(c0 NOT NULL DEFAULT 'xyz', c1 AS(c0) STORED NOT NULL);
REPLACE INTO t0(c0) VALUES(NULL);
SELECT * FROM t0;
} {xyz xyz}
do_execsql_test gencol1-7.20 {
SELECT 99 FROM t0 WHERE 0 = t0.c2 OR t0.c1 BETWEEN t0.c2 AND 1;
} {}
CREATE TABLE t1(
a NOT NULL DEFAULT 'aaa',
b AS(c) NOT NULL,
c NOT NULL DEFAULT 'ccc');
REPLACE INTO t1(a,c) VALUES(NULL,NULL);
SELECT * FROM t1;
} {aaa ccc ccc}
do_execsql_test gencol1-7.21 {
DROP TABLE t1;
CREATE TABLE t1(
a NOT NULL DEFAULT 'aaa',
b AS(c) STORED NOT NULL,
c NOT NULL DEFAULT 'ccc');
REPLACE INTO t1(a,c) VALUES(NULL,NULL);
SELECT * FROM t1;
} {aaa ccc ccc}
do_execsql_test gencol1-7.30 {
CREATE TABLE t2(
a NOT NULL DEFAULT 'aaa',
b AS(a) NOT NULL,
c NOT NULL DEFAULT 'ccc');
REPLACE INTO t2(a,c) VALUES(NULL,NULL);
SELECT * FROM t2;
} {aaa aaa ccc}
do_execsql_test gencol1-7.31 {
DROP TABLE t2;
CREATE TABLE t2(
a NOT NULL DEFAULT 'aaa',
b AS(a) STORED NOT NULL,
c NOT NULL DEFAULT 'ccc');
REPLACE INTO t2(a,c) VALUES(NULL,NULL);
SELECT * FROM t2;
} {aaa aaa ccc}
do_execsql_test gencol1-7.40 {
CREATE TABLE t3(a NOT NULL DEFAULT 123, b AS(a) UNIQUE);
REPLACE INTO t3 VALUES(NULL);
SELECT * FROM t3;
} {123 123}
do_execsql_test gencol1-7.41 {
SELECT * FROM t3 WHERE b=123;
} {123 123}
do_execsql_test gencol1-7.50 {
CREATE TABLE t4(a NOT NULL DEFAULT 123, b AS(a*10+4) STORED UNIQUE);
REPLACE INTO t4 VALUES(NULL);
SELECT * FROM t4;
} {123 1234}
do_execsql_test gencol1-7.51 {
SELECT * FROM t4 WHERE b=1234;
} {123 1234}
# 2019-11-06 ticket 4fc08501f4e56692
do_execsql_test gencol1-8.10 {
@@ -245,9 +310,9 @@ do_catchsql_test gencol1-8.20 {
# 2019-11-21 Problems in the new generated column logic
# reported by Yongheng Chen and Rui Zhong
reset_db
do_execsql_test gencol1-9.10 {
PRAGMA foreign_keys=OFF;
DROP TABLE t1;
CREATE TABLE t1(aa , bb AS (17) UNIQUE);
INSERT INTO t1 VALUES(17);
CREATE TABLE t2(cc);
@@ -483,7 +548,16 @@ do_execsql_test gencol1-18.20 {
SELECT * FROM t0;
} {0 0 0}
# 2019-12-27 ticket de4b04149b9fdeae
#
reset_db
do_catchsql_test gencol1-19.10 {
CREATE TABLE t0(
c0 INT AS(2) UNIQUE,
c1 TEXT UNIQUE,
FOREIGN KEY(c0) REFERENCES t0(c1)
);
INSERT INTO t0(c1) VALUES(0.16334143182538696), (0);
} {1 {UNIQUE constraint failed: t0.c0}}
finish_test