aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2022-10-10 21:21:04 +0000
committerdrh <>2022-10-10 21:21:04 +0000
commitc9ef12f62bfbf808e606dd69d578ef9df3cc9e5a (patch)
treea0ab70dace695841e8f63c5db69287805a1e8c18 /src
parentdb6940ab457adfaa02c102f6f9d9e80e1853d984 (diff)
downloadsqlite-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.c56
-rw-r--r--src/update.c2
-rw-r--r--src/vdbe.c4
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 */