diff options
author | drh <> | 2022-10-10 21:21:04 +0000 |
---|---|---|
committer | drh <> | 2022-10-10 21:21:04 +0000 |
commit | c9ef12f62bfbf808e606dd69d578ef9df3cc9e5a (patch) | |
tree | a0ab70dace695841e8f63c5db69287805a1e8c18 /src | |
parent | db6940ab457adfaa02c102f6f9d9e80e1853d984 (diff) | |
download | sqlite-c9ef12f62bfbf808e606dd69d578ef9df3cc9e5a.tar.gz sqlite-c9ef12f62bfbf808e606dd69d578ef9df3cc9e5a.zip |
Code clean-up for the integrity_check enhancement.
FossilOrigin-Name: a140173102febe9ef8064ee9b95bee489db54caba149e577d69e4d75161bf390
Diffstat (limited to 'src')
-rw-r--r-- | src/pragma.c | 56 | ||||
-rw-r--r-- | src/update.c | 2 | ||||
-rw-r--r-- | src/vdbe.c | 4 |
3 files changed, 30 insertions, 32 deletions
diff --git a/src/pragma.c b/src/pragma.c index c7f349740..7976f83c6 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1782,7 +1782,9 @@ void sqlite3Pragma( /* Fetch the right-most column from the table. This will cause ** 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; while( mxCol>=0 && ((pTab->aCol[mxCol].colFlags & COLFLAG_VIRTUAL)!=0 @@ -1793,6 +1795,7 @@ void sqlite3Pragma( sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); } } + if( !isQuick ){ if( pPk ){ /* Verify WITHOUT ROWID keys are in ascending order */ @@ -1826,9 +1829,10 @@ void sqlite3Pragma( for(j=0; j<pTab->nCol; j++){ char *zErr; Column *pCol = pTab->aCol + j; /* The column to be checked */ - int doError, jmp2; - int p1, p3, p4; /* Operands to the OP_IsType opcode */ - int doTypeCheck; /* Data type check (other than NOT NULL) needed */ + 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 doTypeCheck; /* Check datatypes (besides NOT NULL) */ if( j==pTab->iPKey ) continue; if( bStrict ){ @@ -1837,6 +1841,8 @@ void sqlite3Pragma( doTypeCheck = pCol->affinity>SQLITE_AFF_BLOB; } if( pCol->notNull==0 && !doTypeCheck ) continue; + + /* Compute the operands that will be needed for OP_IsType */ p4 = SQLITE_NULL; if( pCol->colFlags & COLFLAG_VIRTUAL ){ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); @@ -1861,21 +1867,23 @@ void sqlite3Pragma( testcase( p3!=j); } } - doError = doTypeCheck ? sqlite3VdbeMakeLabel(pParse) : 0; + + labelError = sqlite3VdbeMakeLabel(pParse); + labelOk = sqlite3VdbeMakeLabel(pParse); if( pCol->notNull ){ /* (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); VdbeCoverage(v); zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, pCol->zCnName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - if( bStrict && pCol->eCType!=COLTYPE_ANY ){ - sqlite3VdbeGoto(v, doError); + if( doTypeCheck ){ + sqlite3VdbeGoto(v, labelError); + sqlite3VdbeJumpHere(v, jmp2); }else{ - integrityCheckResultRow(v); + /* VDBE byte code will fall thru */ } - sqlite3VdbeJumpHere(v, jmp2); } if( bStrict && doTypeCheck ){ /* (2) Datatype must be exact for non-ANY columns in STRICT tables*/ @@ -1887,7 +1895,7 @@ void sqlite3Pragma( 0x13, /* REAL */ 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) ); sqlite3VdbeChangeP5(v, aStdTypeMask[pCol->eCType-1]); VdbeCoverage(v); @@ -1895,45 +1903,35 @@ void sqlite3Pragma( sqlite3StdType[pCol->eCType-1], pTab->zName, pTab->aCol[j].zCnName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - sqlite3VdbeResolveLabel(v, doError); - integrityCheckResultRow(v); - sqlite3VdbeJumpHere(v, jmp2); - } - if( !bStrict && pCol->affinity==SQLITE_AFF_TEXT ){ + }else if( !bStrict && pCol->affinity==SQLITE_AFF_TEXT ){ /* (3) Datatype for TEXT columns in non-STRICT tables must be ** 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 */ VdbeCoverage(v); zErr = sqlite3MPrintf(db, "NUMERIC value in %s.%s", pTab->zName, pTab->aCol[j].zCnName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - sqlite3VdbeResolveLabel(v, doError); - integrityCheckResultRow(v); - sqlite3VdbeJumpHere(v, jmp2); - } - if( !bStrict && pCol->affinity>=SQLITE_AFF_NUMERIC ){ + }else if( !bStrict && pCol->affinity>=SQLITE_AFF_NUMERIC ){ /* (4) Datatype for numeric columns in non-STRICT tables must not ** be a TEXT value that can be converted to numeric. */ - int jmp3; - jmp2 = sqlite3VdbeAddOp4Int(v, OP_IsType, p1, 0, p3, p4); + sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); sqlite3VdbeChangeP5(v, 0x1b); /* NULL, INT, FLOAT, or BLOB */ VdbeCoverage(v); if( p1>=0 ){ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); } 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 */ VdbeCoverage(v); zErr = sqlite3MPrintf(db, "TEXT value in %s.%s", pTab->zName, pTab->aCol[j].zCnName); 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 */ if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ diff --git a/src/update.c b/src/update.c index a90dfaaea..809b30653 100644 --- a/src/update.c +++ b/src/update.c @@ -59,7 +59,7 @@ static void updateVirtualTable( ** it has been converted into REAL. */ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ - Column *pCol = &pTab->aCol[i]; + Column *pCol; assert( pTab!=0 ); assert( pTab->nCol>i ); pCol = &pTab->aCol[i]; diff --git a/src/vdbe.c b/src/vdbe.c index 4d21eec11..3cfb82866 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2613,7 +2613,7 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ ** P5 bitmask. ** */ -case OP_IsType: { +case OP_IsType: { /* jump */ VdbeCursor *pC; u16 typeMask; u32 serialType; @@ -2624,7 +2624,7 @@ case OP_IsType: { pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pOp->p3>=0 ); - if( pOp->p3<(u32)pC->nHdrParsed ){ + if( pOp->p3<pC->nHdrParsed ){ serialType = pC->aType[pOp->p3]; if( serialType==0 ){ typeMask = 0x10; /* SQLITE_NULL */ |