mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Code clean-up for the integrity_check enhancement.
FossilOrigin-Name: a140173102febe9ef8064ee9b95bee489db54caba149e577d69e4d75161bf390
This commit is contained in:
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Fix\scorner-case\sbugs\sin\sthe\snew\sintegrity_check\slogic.\s\sAll\stests\spass\snow.
|
C Code\sclean-up\sfor\sthe\sintegrity_check\senhancement.
|
||||||
D 2022-10-10T19:38:01.004
|
D 2022-10-10T21:21:04.220
|
||||||
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 LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@@ -581,7 +581,7 @@ F src/parse.y 8e67d820030d2655b9942ffe61c1e7e6b96cea2f2f72183533299393907d0564
|
|||||||
F src/pcache.c f4268f7f73c6a3db12ce22fd25bc68dc42315d19599414ab1207d7cf32f79197
|
F src/pcache.c f4268f7f73c6a3db12ce22fd25bc68dc42315d19599414ab1207d7cf32f79197
|
||||||
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
|
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
|
||||||
F src/pcache1.c dee95e3cd2b61e6512dc814c5ab76d5eb36f0bfc9441dbb4260fccc0d12bbddc
|
F src/pcache1.c dee95e3cd2b61e6512dc814c5ab76d5eb36f0bfc9441dbb4260fccc0d12bbddc
|
||||||
F src/pragma.c a0078de9888c070ef6c73a57d3f3583ba564d8d006e2b88260ec2a9d20f373aa
|
F src/pragma.c 444f596c9e9123d19451ad762917f0f7545e4acecb10f67e09a19f01289cefce
|
||||||
F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
|
F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
|
||||||
F src/prepare.c 1b02be0441eda4579471fea097f678effcbb77ef0c39ab3f703c837822bcd674
|
F src/prepare.c 1b02be0441eda4579471fea097f678effcbb77ef0c39ab3f703c837822bcd674
|
||||||
F src/printf.c e99ee9741e79ae3873458146f59644276657340385ade4e76a5f5d1c25793764
|
F src/printf.c e99ee9741e79ae3873458146f59644276657340385ade4e76a5f5d1c25793764
|
||||||
@@ -655,12 +655,12 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
|||||||
F src/tokenize.c 1305797eab3542a0896b552c6e7669c972c1468e11e92b370533c1f37a37082b
|
F src/tokenize.c 1305797eab3542a0896b552c6e7669c972c1468e11e92b370533c1f37a37082b
|
||||||
F src/treeview.c 07787f67cd297a6d09d04b8d70c06769c60c9c1d9080378f93929c16f8fd3298
|
F src/treeview.c 07787f67cd297a6d09d04b8d70c06769c60c9c1d9080378f93929c16f8fd3298
|
||||||
F src/trigger.c 4163ada044af89d51caba1cb713a73165347b2ec05fe84a283737c134d61fcd5
|
F src/trigger.c 4163ada044af89d51caba1cb713a73165347b2ec05fe84a283737c134d61fcd5
|
||||||
F src/update.c 832cfcf09edcfcc383032b6cc63eb578dc0658c9380e58e1d26f703bba3c5339
|
F src/update.c 5b0302c47cf31b533d5dff04c497ca1d8b9d89c39727e633fbe7b882fd5ac5aa
|
||||||
F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
|
F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
|
||||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||||
F src/util.c 0be191521ff6d2805995f4910f0b6231b42843678b2efdc1abecaf39929a673f
|
F src/util.c 0be191521ff6d2805995f4910f0b6231b42843678b2efdc1abecaf39929a673f
|
||||||
F src/vacuum.c bb346170b0b54c6683bba4a5983aea40485597fdf605c87ec8bc2e199fe88cd8
|
F src/vacuum.c bb346170b0b54c6683bba4a5983aea40485597fdf605c87ec8bc2e199fe88cd8
|
||||||
F src/vdbe.c af03458e12f39cddd6f355ff325059db5431dbe45233fff5a18a7eb0065e535c
|
F src/vdbe.c 387270d575129b0c6ab0d19dad6de5abc1576ce6cc97f30d233ee13775ea4527
|
||||||
F src/vdbe.h 64619af62603dc3c4f5ff6ff6d2c8f389abd667a29ce6007ed44bd22b3211cd0
|
F src/vdbe.h 64619af62603dc3c4f5ff6ff6d2c8f389abd667a29ce6007ed44bd22b3211cd0
|
||||||
F src/vdbeInt.h 17b7461ffcf9ee760d1341731715a419f6b8c763089a7ece25c2e8098d702b3f
|
F src/vdbeInt.h 17b7461ffcf9ee760d1341731715a419f6b8c763089a7ece25c2e8098d702b3f
|
||||||
F src/vdbeapi.c fc3183daf72808b4311b228989120fdbc2dc44972fb0d77d5c453460cc0e5b2c
|
F src/vdbeapi.c fc3183daf72808b4311b228989120fdbc2dc44972fb0d77d5c453460cc0e5b2c
|
||||||
@@ -2002,8 +2002,8 @@ 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 8b1e7f0524637728cebe81c7d3ff8ad8a5a55782eac6409b425dad538024f596
|
P dbab9d52a842085da67f5d0b8e96c665adc16331accf380b4c234e9b05bdb7fb
|
||||||
R cb674d2c5f9d411ede3d4b1200338633
|
R 27cc3a1e54ea78f4322ce43e3f2008e7
|
||||||
U drh
|
U drh
|
||||||
Z b390e30b2deecf15f9935ccee6736a14
|
Z 5bcdf356b09ea5213e990a91977b44f5
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@@ -1 +1 @@
|
|||||||
dbab9d52a842085da67f5d0b8e96c665adc16331accf380b4c234e9b05bdb7fb
|
a140173102febe9ef8064ee9b95bee489db54caba149e577d69e4d75161bf390
|
56
src/pragma.c
56
src/pragma.c
@@ -1782,7 +1782,9 @@ void sqlite3Pragma(
|
|||||||
|
|
||||||
/* Fetch the right-most column from the table. This will cause
|
/* Fetch the right-most column from the table. This will cause
|
||||||
** the entire record header to be parsed and sanity checked. It
|
** the entire record header to be parsed and sanity checked. It
|
||||||
** will also prepopulate the */
|
** will also prepopulate the cursor column cache that is used
|
||||||
|
** by the OP_IsType code, so it is a required step.
|
||||||
|
*/
|
||||||
mxCol = pTab->nCol-1;
|
mxCol = pTab->nCol-1;
|
||||||
while( mxCol>=0
|
while( mxCol>=0
|
||||||
&& ((pTab->aCol[mxCol].colFlags & COLFLAG_VIRTUAL)!=0
|
&& ((pTab->aCol[mxCol].colFlags & COLFLAG_VIRTUAL)!=0
|
||||||
@@ -1793,6 +1795,7 @@ void sqlite3Pragma(
|
|||||||
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
|
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !isQuick ){
|
if( !isQuick ){
|
||||||
if( pPk ){
|
if( pPk ){
|
||||||
/* Verify WITHOUT ROWID keys are in ascending order */
|
/* Verify WITHOUT ROWID keys are in ascending order */
|
||||||
@@ -1826,9 +1829,10 @@ void sqlite3Pragma(
|
|||||||
for(j=0; j<pTab->nCol; j++){
|
for(j=0; j<pTab->nCol; j++){
|
||||||
char *zErr;
|
char *zErr;
|
||||||
Column *pCol = pTab->aCol + j; /* The column to be checked */
|
Column *pCol = pTab->aCol + j; /* The column to be checked */
|
||||||
int doError, jmp2;
|
int labelError; /* Jump here to report an error */
|
||||||
|
int labelOk; /* Jump here if all looks ok */
|
||||||
int p1, p3, p4; /* Operands to the OP_IsType opcode */
|
int p1, p3, p4; /* Operands to the OP_IsType opcode */
|
||||||
int doTypeCheck; /* Data type check (other than NOT NULL) needed */
|
int doTypeCheck; /* Check datatypes (besides NOT NULL) */
|
||||||
|
|
||||||
if( j==pTab->iPKey ) continue;
|
if( j==pTab->iPKey ) continue;
|
||||||
if( bStrict ){
|
if( bStrict ){
|
||||||
@@ -1837,6 +1841,8 @@ void sqlite3Pragma(
|
|||||||
doTypeCheck = pCol->affinity>SQLITE_AFF_BLOB;
|
doTypeCheck = pCol->affinity>SQLITE_AFF_BLOB;
|
||||||
}
|
}
|
||||||
if( pCol->notNull==0 && !doTypeCheck ) continue;
|
if( pCol->notNull==0 && !doTypeCheck ) continue;
|
||||||
|
|
||||||
|
/* Compute the operands that will be needed for OP_IsType */
|
||||||
p4 = SQLITE_NULL;
|
p4 = SQLITE_NULL;
|
||||||
if( pCol->colFlags & COLFLAG_VIRTUAL ){
|
if( pCol->colFlags & COLFLAG_VIRTUAL ){
|
||||||
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
|
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
|
||||||
@@ -1861,21 +1867,23 @@ void sqlite3Pragma(
|
|||||||
testcase( p3!=j);
|
testcase( p3!=j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
doError = doTypeCheck ? sqlite3VdbeMakeLabel(pParse) : 0;
|
|
||||||
|
labelError = sqlite3VdbeMakeLabel(pParse);
|
||||||
|
labelOk = sqlite3VdbeMakeLabel(pParse);
|
||||||
if( pCol->notNull ){
|
if( pCol->notNull ){
|
||||||
/* (1) NOT NULL columns may not contain a NULL */
|
/* (1) NOT NULL columns may not contain a NULL */
|
||||||
jmp2 = sqlite3VdbeAddOp4Int(v, OP_IsType, p1, 0, p3, p4);
|
int jmp2 = sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4);
|
||||||
sqlite3VdbeChangeP5(v, 0x0f);
|
sqlite3VdbeChangeP5(v, 0x0f);
|
||||||
VdbeCoverage(v);
|
VdbeCoverage(v);
|
||||||
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
|
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
|
||||||
pCol->zCnName);
|
pCol->zCnName);
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
||||||
if( bStrict && pCol->eCType!=COLTYPE_ANY ){
|
if( doTypeCheck ){
|
||||||
sqlite3VdbeGoto(v, doError);
|
sqlite3VdbeGoto(v, labelError);
|
||||||
}else{
|
|
||||||
integrityCheckResultRow(v);
|
|
||||||
}
|
|
||||||
sqlite3VdbeJumpHere(v, jmp2);
|
sqlite3VdbeJumpHere(v, jmp2);
|
||||||
|
}else{
|
||||||
|
/* VDBE byte code will fall thru */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if( bStrict && doTypeCheck ){
|
if( bStrict && doTypeCheck ){
|
||||||
/* (2) Datatype must be exact for non-ANY columns in STRICT tables*/
|
/* (2) Datatype must be exact for non-ANY columns in STRICT tables*/
|
||||||
@@ -1887,7 +1895,7 @@ void sqlite3Pragma(
|
|||||||
0x13, /* REAL */
|
0x13, /* REAL */
|
||||||
0x14 /* TEXT */
|
0x14 /* TEXT */
|
||||||
};
|
};
|
||||||
jmp2 = sqlite3VdbeAddOp4Int(v, OP_IsType, p1, 0, p3, p4);
|
sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4);
|
||||||
assert( pCol->eCType>=1 && pCol->eCType<=sizeof(aStdTypeMask) );
|
assert( pCol->eCType>=1 && pCol->eCType<=sizeof(aStdTypeMask) );
|
||||||
sqlite3VdbeChangeP5(v, aStdTypeMask[pCol->eCType-1]);
|
sqlite3VdbeChangeP5(v, aStdTypeMask[pCol->eCType-1]);
|
||||||
VdbeCoverage(v);
|
VdbeCoverage(v);
|
||||||
@@ -1895,45 +1903,35 @@ void sqlite3Pragma(
|
|||||||
sqlite3StdType[pCol->eCType-1],
|
sqlite3StdType[pCol->eCType-1],
|
||||||
pTab->zName, pTab->aCol[j].zCnName);
|
pTab->zName, pTab->aCol[j].zCnName);
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
||||||
sqlite3VdbeResolveLabel(v, doError);
|
}else if( !bStrict && pCol->affinity==SQLITE_AFF_TEXT ){
|
||||||
integrityCheckResultRow(v);
|
|
||||||
sqlite3VdbeJumpHere(v, jmp2);
|
|
||||||
}
|
|
||||||
if( !bStrict && pCol->affinity==SQLITE_AFF_TEXT ){
|
|
||||||
/* (3) Datatype for TEXT columns in non-STRICT tables must be
|
/* (3) Datatype for TEXT columns in non-STRICT tables must be
|
||||||
** NULL, TEXT, or BLOB. */
|
** NULL, TEXT, or BLOB. */
|
||||||
jmp2 = sqlite3VdbeAddOp4Int(v, OP_IsType, p1, 0, p3, p4);
|
sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4);
|
||||||
sqlite3VdbeChangeP5(v, 0x1c); /* NULL, TEXT, or BLOB */
|
sqlite3VdbeChangeP5(v, 0x1c); /* NULL, TEXT, or BLOB */
|
||||||
VdbeCoverage(v);
|
VdbeCoverage(v);
|
||||||
zErr = sqlite3MPrintf(db, "NUMERIC value in %s.%s",
|
zErr = sqlite3MPrintf(db, "NUMERIC value in %s.%s",
|
||||||
pTab->zName, pTab->aCol[j].zCnName);
|
pTab->zName, pTab->aCol[j].zCnName);
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
||||||
sqlite3VdbeResolveLabel(v, doError);
|
}else if( !bStrict && pCol->affinity>=SQLITE_AFF_NUMERIC ){
|
||||||
integrityCheckResultRow(v);
|
|
||||||
sqlite3VdbeJumpHere(v, jmp2);
|
|
||||||
}
|
|
||||||
if( !bStrict && pCol->affinity>=SQLITE_AFF_NUMERIC ){
|
|
||||||
/* (4) Datatype for numeric columns in non-STRICT tables must not
|
/* (4) Datatype for numeric columns in non-STRICT tables must not
|
||||||
** be a TEXT value that can be converted to numeric. */
|
** be a TEXT value that can be converted to numeric. */
|
||||||
int jmp3;
|
sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4);
|
||||||
jmp2 = sqlite3VdbeAddOp4Int(v, OP_IsType, p1, 0, p3, p4);
|
|
||||||
sqlite3VdbeChangeP5(v, 0x1b); /* NULL, INT, FLOAT, or BLOB */
|
sqlite3VdbeChangeP5(v, 0x1b); /* NULL, INT, FLOAT, or BLOB */
|
||||||
VdbeCoverage(v);
|
VdbeCoverage(v);
|
||||||
if( p1>=0 ){
|
if( p1>=0 ){
|
||||||
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
|
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp4(v, OP_Affinity, 3, 1, 0, "C", P4_STATIC);
|
sqlite3VdbeAddOp4(v, OP_Affinity, 3, 1, 0, "C", P4_STATIC);
|
||||||
jmp3 = sqlite3VdbeAddOp4Int(v, OP_IsType, -1, 0, 3, p4);
|
sqlite3VdbeAddOp4Int(v, OP_IsType, -1, labelOk, 3, p4);
|
||||||
sqlite3VdbeChangeP5(v, 0x1c); /* NULL, TEXT, or BLOB */
|
sqlite3VdbeChangeP5(v, 0x1c); /* NULL, TEXT, or BLOB */
|
||||||
VdbeCoverage(v);
|
VdbeCoverage(v);
|
||||||
zErr = sqlite3MPrintf(db, "TEXT value in %s.%s",
|
zErr = sqlite3MPrintf(db, "TEXT value in %s.%s",
|
||||||
pTab->zName, pTab->aCol[j].zCnName);
|
pTab->zName, pTab->aCol[j].zCnName);
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
||||||
sqlite3VdbeResolveLabel(v, doError);
|
|
||||||
integrityCheckResultRow(v);
|
|
||||||
sqlite3VdbeJumpHere(v, jmp2);
|
|
||||||
sqlite3VdbeJumpHere(v, jmp3);
|
|
||||||
}
|
}
|
||||||
|
sqlite3VdbeResolveLabel(v, labelError);
|
||||||
|
integrityCheckResultRow(v);
|
||||||
|
sqlite3VdbeResolveLabel(v, labelOk);
|
||||||
}
|
}
|
||||||
/* Verify CHECK constraints */
|
/* Verify CHECK constraints */
|
||||||
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
|
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
|
||||||
|
@@ -59,7 +59,7 @@ static void updateVirtualTable(
|
|||||||
** it has been converted into REAL.
|
** it has been converted into REAL.
|
||||||
*/
|
*/
|
||||||
void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
|
void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
|
||||||
Column *pCol = &pTab->aCol[i];
|
Column *pCol;
|
||||||
assert( pTab!=0 );
|
assert( pTab!=0 );
|
||||||
assert( pTab->nCol>i );
|
assert( pTab->nCol>i );
|
||||||
pCol = &pTab->aCol[i];
|
pCol = &pTab->aCol[i];
|
||||||
|
@@ -2613,7 +2613,7 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
|
|||||||
** P5 bitmask.
|
** P5 bitmask.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
case OP_IsType: {
|
case OP_IsType: { /* jump */
|
||||||
VdbeCursor *pC;
|
VdbeCursor *pC;
|
||||||
u16 typeMask;
|
u16 typeMask;
|
||||||
u32 serialType;
|
u32 serialType;
|
||||||
@@ -2624,7 +2624,7 @@ case OP_IsType: {
|
|||||||
pC = p->apCsr[pOp->p1];
|
pC = p->apCsr[pOp->p1];
|
||||||
assert( pC!=0 );
|
assert( pC!=0 );
|
||||||
assert( pOp->p3>=0 );
|
assert( pOp->p3>=0 );
|
||||||
if( pOp->p3<(u32)pC->nHdrParsed ){
|
if( pOp->p3<pC->nHdrParsed ){
|
||||||
serialType = pC->aType[pOp->p3];
|
serialType = pC->aType[pOp->p3];
|
||||||
if( serialType==0 ){
|
if( serialType==0 ){
|
||||||
typeMask = 0x10; /* SQLITE_NULL */
|
typeMask = 0x10; /* SQLITE_NULL */
|
||||||
|
Reference in New Issue
Block a user