mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-14 00:22:38 +03:00
Merge integrity_check and other improvements from trunk.
FossilOrigin-Name: fe073905081b421405ca425ca03c5b8b0ff5f2c8
This commit is contained in:
@@ -290,6 +290,7 @@ struct Stat4Accum {
|
||||
Stat4Sample *aBest; /* Array of nCol best samples */
|
||||
int iMin; /* Index in a[] of entry with minimum score */
|
||||
int nSample; /* Current number of samples */
|
||||
int nMaxEqZero; /* Max leading 0 in anEq[] for any a[] entry */
|
||||
int iGet; /* Index of current sample accessed by stat_get() */
|
||||
Stat4Sample *a; /* Array of mxSample Stat4Sample objects */
|
||||
sqlite3 *db; /* Database connection, for malloc() */
|
||||
@@ -554,6 +555,13 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
|
||||
assert( IsStat4 || nEqZero==0 );
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0
|
||||
** values in the anEq[] array of any sample in Stat4Accum.a[]. In
|
||||
** other words, if nMaxEqZero is n, then it is guaranteed that there
|
||||
** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */
|
||||
if( nEqZero>p->nMaxEqZero ){
|
||||
p->nMaxEqZero = nEqZero;
|
||||
}
|
||||
if( pNew->isPSample==0 ){
|
||||
Stat4Sample *pUpgrade = 0;
|
||||
assert( pNew->anEq[pNew->iCol]>0 );
|
||||
@@ -651,12 +659,22 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the anEq[] fields of any samples already collected. */
|
||||
/* Check that no sample contains an anEq[] entry with an index of
|
||||
** p->nMaxEqZero or greater set to zero. */
|
||||
for(i=p->nSample-1; i>=0; i--){
|
||||
int j;
|
||||
for(j=iChng; j<p->nCol; j++){
|
||||
if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
|
||||
for(j=p->nMaxEqZero; j<p->nCol; j++) assert( p->a[i].anEq[j]>0 );
|
||||
}
|
||||
|
||||
/* Update the anEq[] fields of any samples already collected. */
|
||||
if( iChng<p->nMaxEqZero ){
|
||||
for(i=p->nSample-1; i>=0; i--){
|
||||
int j;
|
||||
for(j=iChng; j<p->nCol; j++){
|
||||
if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
|
||||
}
|
||||
}
|
||||
p->nMaxEqZero = iChng;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1115,6 +1115,7 @@ void sqlite3AddNotNull(Parse *pParse, int onError){
|
||||
p = pParse->pNewTable;
|
||||
if( p==0 || NEVER(p->nCol<1) ) return;
|
||||
p->aCol[p->nCol-1].notNull = (u8)onError;
|
||||
p->tabFlags |= TF_HasNotNull;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
52
src/os_win.c
52
src/os_win.c
@@ -352,7 +352,34 @@ struct winVfsAppData {
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_CREATE
|
||||
# define SQLITE_WIN32_HEAP_CREATE (TRUE)
|
||||
# define SQLITE_WIN32_HEAP_CREATE (TRUE)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the maximum possible initial size of the Win32-specific heap, in
|
||||
* bytes.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_MAX_INIT_SIZE
|
||||
# define SQLITE_WIN32_HEAP_MAX_INIT_SIZE (4294967295U)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the extra space for the initial size of the Win32-specific heap,
|
||||
* in bytes. This value may be zero.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_INIT_EXTRA
|
||||
# define SQLITE_WIN32_HEAP_INIT_EXTRA (4194304)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Calculate the maximum legal cache size, in pages, based on the maximum
|
||||
* possible initial heap size and the default page size, setting aside the
|
||||
* needed extra space.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_MAX_CACHE_SIZE
|
||||
# define SQLITE_WIN32_MAX_CACHE_SIZE (((SQLITE_WIN32_HEAP_MAX_INIT_SIZE) - \
|
||||
(SQLITE_WIN32_HEAP_INIT_EXTRA)) / \
|
||||
(SQLITE_DEFAULT_PAGE_SIZE))
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -361,25 +388,36 @@ struct winVfsAppData {
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_CACHE_SIZE
|
||||
# if SQLITE_DEFAULT_CACHE_SIZE>=0
|
||||
# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
|
||||
# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
|
||||
# else
|
||||
# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
|
||||
# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure that the calculated cache size, in pages, cannot cause the
|
||||
* initial size of the Win32-specific heap to exceed the maximum amount
|
||||
* of memory that can be specified in the call to HeapCreate.
|
||||
*/
|
||||
#if SQLITE_WIN32_CACHE_SIZE>SQLITE_WIN32_MAX_CACHE_SIZE
|
||||
# undef SQLITE_WIN32_CACHE_SIZE
|
||||
# define SQLITE_WIN32_CACHE_SIZE (2000)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The initial size of the Win32-specific heap. This value may be zero.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
|
||||
# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
|
||||
(SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
|
||||
# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
|
||||
(SQLITE_DEFAULT_PAGE_SIZE) + \
|
||||
(SQLITE_WIN32_HEAP_INIT_EXTRA))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The maximum size of the Win32-specific heap. This value may be zero.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_MAX_SIZE
|
||||
# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
|
||||
# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -387,7 +425,7 @@ struct winVfsAppData {
|
||||
* zero for the default behavior.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_FLAGS
|
||||
# define SQLITE_WIN32_HEAP_FLAGS (0)
|
||||
# define SQLITE_WIN32_HEAP_FLAGS (0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1000,7 +1000,7 @@ expr(A) ::= expr(A) STAR|SLASH|REM(OP) expr(Y).
|
||||
{spanBinaryExpr(pParse,@OP,&A,&Y);}
|
||||
expr(A) ::= expr(A) CONCAT(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
|
||||
%type likeop {Token}
|
||||
likeop(A) ::= LIKE_KW|MATCH(X). {A=X;/*A-overwrites-X*/}
|
||||
likeop(A) ::= LIKE_KW|MATCH(A).
|
||||
likeop(A) ::= NOT LIKE_KW|MATCH(X). {A=X; A.n|=0x80000000; /*A-overwrite-X*/}
|
||||
expr(A) ::= expr(A) likeop(OP) expr(Y). [LIKE_KW] {
|
||||
ExprList *pList;
|
||||
|
||||
116
src/pragma.c
116
src/pragma.c
@@ -295,6 +295,22 @@ static const PragmaName *pragmaLocate(const char *zName){
|
||||
return lwr>upr ? 0 : &aPragmaName[mid];
|
||||
}
|
||||
|
||||
/*
|
||||
** Helper subroutine for PRAGMA integrity_check:
|
||||
**
|
||||
** Generate code to output a single-column result row with the result
|
||||
** held in register regResult. Decrement the result count and halt if
|
||||
** the maximum number of result rows have been issued.
|
||||
*/
|
||||
static int integrityCheckResultRow(Vdbe *v, int regResult){
|
||||
int addr;
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 1);
|
||||
addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1);
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/*
|
||||
** Process a pragma statement.
|
||||
**
|
||||
@@ -1381,9 +1397,17 @@ void sqlite3Pragma(
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
|
||||
/* Pragma "quick_check" is reduced version of
|
||||
/* PRAGMA integrity_check
|
||||
** PRAGMA integrity_check(N)
|
||||
** PRAGMA quick_check
|
||||
** PRAGMA quick_check(N)
|
||||
**
|
||||
** Verify the integrity of the database.
|
||||
**
|
||||
** The "quick_check" is reduced version of
|
||||
** integrity_check designed to detect most database corruption
|
||||
** without most of the overhead of a full integrity-check.
|
||||
** without the overhead of cross-checking indexes. Quick_check
|
||||
** is linear time wherease integrity_check is O(NlogN).
|
||||
*/
|
||||
case PragTyp_INTEGRITY_CHECK: {
|
||||
int i, j, addr, mxErr;
|
||||
@@ -1414,7 +1438,7 @@ void sqlite3Pragma(
|
||||
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* reg[1] holds errors left */
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */
|
||||
|
||||
/* Do an integrity check on each database file */
|
||||
for(i=0; i<db->nDb; i++){
|
||||
@@ -1429,10 +1453,6 @@ void sqlite3Pragma(
|
||||
if( iDb>=0 && i!=iDb ) continue;
|
||||
|
||||
sqlite3CodeVerifySchema(pParse, i);
|
||||
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
|
||||
/* Do an integrity check of the B-Tree
|
||||
**
|
||||
@@ -1472,12 +1492,12 @@ void sqlite3Pragma(
|
||||
P4_DYNAMIC);
|
||||
sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
|
||||
integrityCheckResultRow(v, 2);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
|
||||
/* Make sure all the indices are constructed correctly.
|
||||
*/
|
||||
for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
|
||||
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
|
||||
Table *pTab = sqliteHashData(x);
|
||||
Index *pIdx, *pPk;
|
||||
Index *pPrior = 0;
|
||||
@@ -1485,12 +1505,13 @@ void sqlite3Pragma(
|
||||
int iDataCur, iIdxCur;
|
||||
int r1 = -1;
|
||||
|
||||
if( pTab->pIndex==0 ) continue;
|
||||
if( pTab->pCheck==0
|
||||
&& (pTab->tabFlags & TF_HasNotNull)==0
|
||||
&& (pTab->pIndex==0 || isQuick)
|
||||
){
|
||||
continue; /* No additional checks needed for this table */
|
||||
}
|
||||
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
|
||||
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
sqlite3ExprCacheClear(pParse);
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
|
||||
1, 0, &iDataCur, &iIdxCur);
|
||||
@@ -1505,24 +1526,42 @@ void sqlite3Pragma(
|
||||
/* Verify that all NOT NULL columns really are NOT NULL */
|
||||
for(j=0; j<pTab->nCol; j++){
|
||||
char *zErr;
|
||||
int jmp2, jmp3;
|
||||
int jmp2;
|
||||
if( j==pTab->iPKey ) continue;
|
||||
if( pTab->aCol[j].notNull==0 ) continue;
|
||||
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
|
||||
jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
|
||||
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
|
||||
pTab->aCol[j].zName);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
|
||||
jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp0(v, OP_Halt);
|
||||
integrityCheckResultRow(v, 3);
|
||||
sqlite3VdbeJumpHere(v, jmp2);
|
||||
sqlite3VdbeJumpHere(v, jmp3);
|
||||
}
|
||||
/* Verify CHECK constraints */
|
||||
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
|
||||
int addrCkFault = sqlite3VdbeMakeLabel(v);
|
||||
int addrCkOk = sqlite3VdbeMakeLabel(v);
|
||||
ExprList *pCheck = pTab->pCheck;
|
||||
char *zErr;
|
||||
int k;
|
||||
pParse->iSelfTab = iDataCur;
|
||||
sqlite3ExprCachePush(pParse);
|
||||
for(k=pCheck->nExpr-1; k>0; k--){
|
||||
sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
|
||||
}
|
||||
sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk,
|
||||
SQLITE_JUMPIFNULL);
|
||||
sqlite3VdbeResolveLabel(v, addrCkFault);
|
||||
zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
|
||||
pTab->zName);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
||||
integrityCheckResultRow(v, 3);
|
||||
sqlite3VdbeResolveLabel(v, addrCkOk);
|
||||
sqlite3ExprCachePop(pParse);
|
||||
}
|
||||
/* Validate index entries for the current row */
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){
|
||||
int jmp2, jmp3, jmp4, jmp5;
|
||||
int ckUniq = sqlite3VdbeMakeLabel(v);
|
||||
if( pPk==pIdx ) continue;
|
||||
@@ -1533,16 +1572,13 @@ void sqlite3Pragma(
|
||||
/* Verify that an index entry exists for the current table row */
|
||||
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
|
||||
pIdx->nColumn); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
|
||||
sqlite3VdbeLoadString(v, 3, "row ");
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
|
||||
sqlite3VdbeLoadString(v, 4, " missing from index ");
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
|
||||
jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
|
||||
jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp0(v, OP_Halt);
|
||||
jmp4 = integrityCheckResultRow(v, 3);
|
||||
sqlite3VdbeJumpHere(v, jmp2);
|
||||
/* For UNIQUE indexes, verify that only one entry exists with the
|
||||
** current key. The entry is unique if (1) any column is NULL
|
||||
@@ -1563,7 +1599,6 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeJumpHere(v, jmp6);
|
||||
sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
|
||||
pIdx->nKeyCol); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
|
||||
sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
|
||||
sqlite3VdbeGoto(v, jmp5);
|
||||
sqlite3VdbeResolveLabel(v, uniqOk);
|
||||
@@ -1574,19 +1609,18 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
|
||||
sqlite3VdbeJumpHere(v, loopTop-1);
|
||||
#ifndef SQLITE_OMIT_BTREECOUNT
|
||||
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
if( pPk==pIdx ) continue;
|
||||
addr = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
|
||||
sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
|
||||
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
|
||||
sqlite3VdbeLoadString(v, 3, pIdx->zName);
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
|
||||
if( !isQuick ){
|
||||
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
if( pPk==pIdx ) continue;
|
||||
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
|
||||
addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v);
|
||||
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
|
||||
sqlite3VdbeLoadString(v, 3, pIdx->zName);
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
|
||||
integrityCheckResultRow(v, 7);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_OMIT_BTREECOUNT */
|
||||
}
|
||||
@@ -1595,7 +1629,7 @@ void sqlite3Pragma(
|
||||
static const int iLn = VDBE_OFFSET_LINENO(2);
|
||||
static const VdbeOpList endCode[] = {
|
||||
{ OP_AddImm, 1, 0, 0}, /* 0 */
|
||||
{ OP_If, 1, 4, 0}, /* 1 */
|
||||
{ OP_IfNotZero, 1, 4, 0}, /* 1 */
|
||||
{ OP_String8, 0, 3, 0}, /* 2 */
|
||||
{ OP_ResultRow, 3, 1, 0}, /* 3 */
|
||||
};
|
||||
@@ -1603,7 +1637,7 @@ void sqlite3Pragma(
|
||||
|
||||
aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
|
||||
if( aOp ){
|
||||
aOp[0].p2 = -mxErr;
|
||||
aOp[0].p2 = 1-mxErr;
|
||||
aOp[2].p4type = P4_STATIC;
|
||||
aOp[2].p4.z = "ok";
|
||||
}
|
||||
|
||||
@@ -1889,6 +1889,7 @@ struct Table {
|
||||
#define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */
|
||||
#define TF_StatsUsed 0x0100 /* Query planner decisions affected by
|
||||
** Index.aiRowLogEst[] values */
|
||||
#define TF_HasNotNull 0x0200 /* Contains NOT NULL constraints */
|
||||
|
||||
/*
|
||||
** Test to see whether or not a table is a virtual table. This is
|
||||
|
||||
20
src/vdbe.c
20
src/vdbe.c
@@ -1669,21 +1669,21 @@ case OP_Function: {
|
||||
for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
|
||||
}
|
||||
|
||||
memAboutToChange(p, pCtx->pOut);
|
||||
memAboutToChange(p, pOut);
|
||||
#ifdef SQLITE_DEBUG
|
||||
for(i=0; i<pCtx->argc; i++){
|
||||
assert( memIsValid(pCtx->argv[i]) );
|
||||
REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
|
||||
}
|
||||
#endif
|
||||
MemSetTypeFlag(pCtx->pOut, MEM_Null);
|
||||
MemSetTypeFlag(pOut, MEM_Null);
|
||||
pCtx->fErrorOrAux = 0;
|
||||
(*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
|
||||
|
||||
/* If the function returned an error, throw an exception */
|
||||
if( pCtx->fErrorOrAux ){
|
||||
if( pCtx->isError ){
|
||||
sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
|
||||
sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut));
|
||||
rc = pCtx->isError;
|
||||
}
|
||||
sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
|
||||
@@ -1692,12 +1692,12 @@ case OP_Function: {
|
||||
|
||||
/* Copy the result of the function into register P3 */
|
||||
if( pOut->flags & (MEM_Str|MEM_Blob) ){
|
||||
sqlite3VdbeChangeEncoding(pCtx->pOut, encoding);
|
||||
if( sqlite3VdbeMemTooBig(pCtx->pOut) ) goto too_big;
|
||||
sqlite3VdbeChangeEncoding(pOut, encoding);
|
||||
if( sqlite3VdbeMemTooBig(pOut) ) goto too_big;
|
||||
}
|
||||
|
||||
REGISTER_TRACE(pOp->p3, pCtx->pOut);
|
||||
UPDATE_MAX_BLOBSIZE(pCtx->pOut);
|
||||
REGISTER_TRACE(pOp->p3, pOut);
|
||||
UPDATE_MAX_BLOBSIZE(pOut);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5648,7 +5648,7 @@ case OP_DropTrigger: {
|
||||
** register P1 the text of an error message describing any problems.
|
||||
** If no problems are found, store a NULL in register P1.
|
||||
**
|
||||
** The register P3 contains the maximum number of allowed errors.
|
||||
** The register P3 contains one less than the maximum number of allowed errors.
|
||||
** At most reg(P3) errors will be reported.
|
||||
** In other words, the analysis stops as soon as reg(P1) errors are
|
||||
** seen. Reg(P1) is updated with the number of errors remaining.
|
||||
@@ -5681,14 +5681,14 @@ case OP_IntegrityCk: {
|
||||
assert( pOp->p5<db->nDb );
|
||||
assert( DbMaskTest(p->btreeMask, pOp->p5) );
|
||||
z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
|
||||
(int)pnErr->u.i, &nErr);
|
||||
pnErr->u.i -= nErr;
|
||||
(int)pnErr->u.i+1, &nErr);
|
||||
sqlite3VdbeMemSetNull(pIn1);
|
||||
if( nErr==0 ){
|
||||
assert( z==0 );
|
||||
}else if( z==0 ){
|
||||
goto no_mem;
|
||||
}else{
|
||||
pnErr->u.i -= nErr-1;
|
||||
sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
|
||||
}
|
||||
UPDATE_MAX_BLOBSIZE(pIn1);
|
||||
|
||||
@@ -2609,13 +2609,13 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
** one, or the complete transaction if there is no statement transaction.
|
||||
*/
|
||||
|
||||
if( p->magic!=VDBE_MAGIC_RUN ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
if( db->mallocFailed ){
|
||||
p->rc = SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
closeAllCursors(p);
|
||||
if( p->magic!=VDBE_MAGIC_RUN ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
checkActiveVdbeCnt(db);
|
||||
|
||||
/* No commit or rollback needed if the program never started or if the
|
||||
|
||||
Reference in New Issue
Block a user