Add the SQLITE_NOTNULL P5 code for comparison operations - really a composite

of SQLITE_NULLEQ and SQLITE_JUMPIFNULL.  This flag indicates that NULL operands
are not possible and raises and assert() if NULL operands are seen.
Also omit an unnecessary scan of the sqlite_sequence table when writing
into an AUTOINCREMENT table.

FossilOrigin-Name: d2c047f304848e49864ed8c216b48fd671fa3916
This commit is contained in:
drh 2014-02-19 14:20:49 +00:00
parent c0bf493ea5
commit 3d77dee935
7 changed files with 27 additions and 24 deletions

View File

@ -1,5 +1,5 @@
C Make\ssure\sa\smulti-row\sVALUES\sclause\sworks\scorrectly\sin\sa\scompound\sSELECT. C Add\sthe\sSQLITE_NOTNULL\sP5\scode\sfor\scomparison\soperations\s-\sreally\sa\scomposite\nof\sSQLITE_NULLEQ\sand\sSQLITE_JUMPIFNULL.\s\sThis\sflag\sindicates\sthat\sNULL\soperands\nare\snot\spossible\sand\sraises\sand\sassert()\sif\sNULL\soperands\sare\sseen.\nAlso\somit\san\sunnecessary\sscan\sof\sthe\ssqlite_sequence\stable\swhen\swriting\ninto\san\sAUTOINCREMENT\stable.
D 2014-02-19T01:31:02.841 D 2014-02-19T14:20:49.685
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -156,7 +156,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 1a630c6579b05d93530d4289182a4e8449e722f2 F src/alter.c 75a0b861e98968c0f3b27606e7d9462228d04827
F src/analyze.c 69761e1677142d180a9f55250dee2952f45e4793 F src/analyze.c 69761e1677142d180a9f55250dee2952f45e4793
F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
@ -174,13 +174,13 @@ F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
F src/delete.c cdd57149543bb28304d8f717c243f2a86b1fc280 F src/delete.c cdd57149543bb28304d8f717c243f2a86b1fc280
F src/expr.c 014b8087a15c4c314bdd798cb1cb0b32693f8b40 F src/expr.c 014b8087a15c4c314bdd798cb1cb0b32693f8b40
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 3cd6ce998404fb1b7203d886d6fdff71cf3c8846 F src/fkey.c 5269ef07b100763134f71b889327c333bd0989cf
F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5 F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5
F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486
F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 5d5e1d78f74804739b424c92346bdc26c146dfa4 F src/insert.c 429adb670176eb5471be9867ff7c88a190b23cb3
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
@ -221,7 +221,7 @@ F src/shell.c 3dd86bf73ccd079f0e32ef5069600586085e8239
F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80 F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 22111056d7d5c404fef783b13088ef87d98074d0 F src/sqliteInt.h 616f8a225bfd6cf09f7f5906c7b91b29a3591b34
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@ -277,7 +277,7 @@ F src/update.c 16d6555a32298da18ce6e2a00637c462d9e3ac97
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c 6e3d5d4c68076c09724c74bc5c39985a204e55a0 F src/vdbe.c 16c220ae23bbd6755f66bb32eb4c8c0fadda6c8f
F src/vdbe.h f429f5e5e14b02acbdffb2b2e8ba6e865e66e320 F src/vdbe.h f429f5e5e14b02acbdffb2b2e8ba6e865e66e320
F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8 F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8
F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820 F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820
@ -1151,7 +1151,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P b97825646996792d0a67b83f135658027c8569ca P 85b355cfb40e8dbeb171980204ffad897184063f
R e0d510b78dfc0d79538a4222d29a9363 R 6054409536840db43eb58dd38378a2df
U drh U drh
Z f971c993fbd0c297278e42fafe3ac2dc Z 59cedb1de1bf2e430d47d82062cddf85

View File

@ -1 +1 @@
85b355cfb40e8dbeb171980204ffad897184063f d2c047f304848e49864ed8c216b48fd671fa3916

View File

@ -605,7 +605,7 @@ void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeUsesBtree(v, iDb);
sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2); sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); VdbeCoverage(v); sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
sqlite3VdbeJumpHere(v, j1); sqlite3VdbeJumpHere(v, j1);
sqlite3ReleaseTempReg(pParse, r1); sqlite3ReleaseTempReg(pParse, r1);

View File

@ -369,6 +369,7 @@ static void fkLookupParent(
** increment the constraint-counter. */ ** increment the constraint-counter. */
if( pTab==pFKey->pFrom && nIncr==1 ){ if( pTab==pFKey->pFrom && nIncr==1 ){
sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
} }
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);

View File

@ -304,7 +304,7 @@ void sqlite3AutoincrementEnd(Parse *pParse){
assert( v ); assert( v );
for(p = pParse->pAinc; p; p = p->pNext){ for(p = pParse->pAinc; p; p = p->pNext){
Db *pDb = &db->aDb[p->iDb]; Db *pDb = &db->aDb[p->iDb];
int j1, j2, j3, j4, j5; int j1;
int iRec; int iRec;
int memId = p->regCtr; int memId = p->regCtr;
@ -312,17 +312,8 @@ void sqlite3AutoincrementEnd(Parse *pParse){
assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v); j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v);
j2 = sqlite3VdbeAddOp0(v, OP_Rewind); VdbeCoverage(v);
j3 = sqlite3VdbeAddOp3(v, OP_Column, 0, 0, iRec);
j4 = sqlite3VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Next, 0, j3); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, j2);
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1); sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1);
j5 = sqlite3VdbeAddOp0(v, OP_Goto);
sqlite3VdbeJumpHere(v, j4);
sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
sqlite3VdbeJumpHere(v, j1); sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeJumpHere(v, j5);
sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec); sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec);
sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1); sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND); sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
@ -1275,6 +1266,7 @@ void sqlite3GenerateConstraintChecks(
** it might have changed. Skip the conflict logic below if the rowid ** it might have changed. Skip the conflict logic below if the rowid
** is unchanged. */ ** is unchanged. */
sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData); sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
VdbeCoverage(v); VdbeCoverage(v);
} }
@ -1446,6 +1438,7 @@ void sqlite3GenerateConstraintChecks(
** is different from old-rowid */ ** is different from old-rowid */
if( isUpdate ){ if( isUpdate ){
sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData); sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
VdbeCoverage(v); VdbeCoverage(v);
} }
}else{ }else{
@ -1481,7 +1474,10 @@ void sqlite3GenerateConstraintChecks(
} }
sqlite3VdbeAddOp4(v, op, sqlite3VdbeAddOp4(v, op,
regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
); VdbeCoverage(v); );
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
VdbeCoverageIf(v, op==OP_Eq);
VdbeCoverageIf(v, op==OP_Ne);
} }
} }
} }

View File

@ -1314,10 +1314,16 @@ struct CollSeq {
/* /*
** Additional bit values that can be ORed with an affinity without ** Additional bit values that can be ORed with an affinity without
** changing the affinity. ** changing the affinity.
**
** The SQLITE_NOTNULL flag is a combination of NULLEQ and JUMPIFNULL.
** It causes an assert() to fire if either operand to a comparison
** operator is NULL. It is added to certain comparison operators to
** prove that the operands are always NOT NULL.
*/ */
#define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */ #define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */
#define SQLITE_STOREP2 0x10 /* Store result in reg[P2] rather than jump */ #define SQLITE_STOREP2 0x10 /* Store result in reg[P2] rather than jump */
#define SQLITE_NULLEQ 0x80 /* NULL=NULL */ #define SQLITE_NULLEQ 0x80 /* NULL=NULL */
#define SQLITE_NOTNULL 0x88 /* Assert that operands are never NULL */
/* /*
** An object of this type is created for each virtual table present in ** An object of this type is created for each virtual table present in

View File

@ -1891,6 +1891,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
*/ */
assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
assert( (flags1 & MEM_Cleared)==0 ); assert( (flags1 & MEM_Cleared)==0 );
assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 );
if( (flags1&MEM_Null)!=0 if( (flags1&MEM_Null)!=0
&& (flags3&MEM_Null)!=0 && (flags3&MEM_Null)!=0
&& (flags3&MEM_Cleared)==0 && (flags3&MEM_Cleared)==0
@ -4833,7 +4834,6 @@ case OP_Clear: {
nChange = 0; nChange = 0;
assert( p->readOnly==0 ); assert( p->readOnly==0 );
assert( pOp->p1!=1 );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 );
rc = sqlite3BtreeClearTable( rc = sqlite3BtreeClearTable(
db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0)