Index: src/btree.c ================================================================== --- src/btree.c +++ src/btree.c @@ -4609,11 +4609,11 @@ lwr = 0; upr = pPage->nCell-1; assert( biasRight==0 || biasRight==1 ); idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */ pCur->aiIdx[pCur->iPage] = (u16)idx; - if( pPage->intKey ){ + if( xRecordCompare==0 ){ for(;;){ i64 nCellKey; pCell = findCell(pPage, idx) + pPage->childPtrSize; if( pPage->hasData ){ while( 0x80 <= *(pCell++) ){ Index: src/select.c ================================================================== --- src/select.c +++ src/select.c @@ -1520,11 +1520,11 @@ for(j=cnt=0; j1 && sqlite3Isdigit(zName[k]); k--){} - if( zName[k]==':' ) nName = k; + if( k>=0 && zName[k]==':' ) nName = k; zName[nName] = 0; zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt); sqlite3DbFree(db, zName); zName = zNewName; j = -1; Index: src/test5.c ================================================================== --- src/test5.c +++ src/test5.c @@ -74,11 +74,10 @@ if( Tcl_GetIntFromObj(interp, objv[1], &repeat_count) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[2], &do_calls) ) return TCL_ERROR; val.flags = MEM_Str|MEM_Term|MEM_Static; val.z = "hello world"; - val.memType = MEM_Str; val.enc = SQLITE_UTF8; for(i=0; ip1+i, &pMem[i]); } if( db->mallocFailed ) goto no_mem; /* Return SQLITE_ROW @@ -1497,11 +1495,10 @@ pArg = &aMem[pOp->p2]; for(i=0; ip2+i, pArg); } assert( pOp->p4type==P4_FUNCDEF ); ctx.pFunc = pOp->p4.pFunc; @@ -5553,11 +5550,10 @@ assert( apVal || n==0 ); for(i=0; ip4.pFunc; assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); ctx.pMem = pMem = &aMem[pOp->p3]; pMem->n++; @@ -5987,11 +5983,10 @@ { res = 0; apArg = p->apArg; for(i = 0; iinVtabMethod = 1; rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg); p->inVtabMethod = 0; @@ -6194,11 +6189,10 @@ apArg = p->apArg; pX = &aMem[pOp->p3]; for(i=0; ivtabOnConflict = pOp->p5; rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid); Index: src/vdbeInt.h ================================================================== --- src/vdbeInt.h +++ src/vdbeInt.h @@ -166,11 +166,10 @@ RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ } u; int n; /* Number of characters in string value, excluding '\0' */ u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ - u8 memType; /* Lower 5 bits of flags */ u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ #ifdef SQLITE_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */ #endif @@ -193,10 +192,11 @@ #define MEM_Null 0x0001 /* Value is NULL */ #define MEM_Str 0x0002 /* Value is a string */ #define MEM_Int 0x0004 /* Value is an integer */ #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ +#define MEM_AffMask 0x001f /* Mask of affinity bits */ #define MEM_RowSet 0x0020 /* Value is a RowSet object */ #define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ #define MEM_Undefined 0x0080 /* Value is undefined */ #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ #define MEM_TypeMask 0x01ff /* Mask of type bits */ @@ -451,12 +451,10 @@ const char *sqlite3OpcodeName(int); int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); int sqlite3VdbeCloseStatement(Vdbe *, int); void sqlite3VdbeFrameDelete(VdbeFrame*); int sqlite3VdbeFrameRestore(VdbeFrame *); -#define sqlite3VdbeMemStoreType(X) (X)->memType = (u8)((X)->flags&0x1f) -/* void sqlite3VdbeMemStoreType(Mem *pMem); */ void sqlite3VdbePreUpdateHook( Vdbe *, VdbeCursor *, int, const char*, Table *, i64, int); int sqlite3VdbeTransferError(Vdbe *p); int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); Index: src/vdbeapi.c ================================================================== --- src/vdbeapi.c +++ src/vdbeapi.c @@ -133,11 +133,10 @@ */ const void *sqlite3_value_blob(sqlite3_value *pVal){ Mem *p = (Mem*)pVal; if( p->flags & (MEM_Blob|MEM_Str) ){ sqlite3VdbeMemExpandBlob(p); - p->flags &= ~MEM_Str; p->flags |= MEM_Blob; return p->n ? p->z : 0; }else{ return sqlite3_value_text(pVal); } @@ -204,11 +203,11 @@ SQLITE_INTEGER, /* 0x1c */ SQLITE_NULL, /* 0x1d */ SQLITE_INTEGER, /* 0x1e */ SQLITE_NULL, /* 0x1f */ }; - return aType[pVal->memType&0x1f]; + return aType[pVal->flags&MEM_AffMask]; } /**************************** sqlite3_result_ ******************************* ** The following routines are used by user-defined functions to specify ** the function result. @@ -730,23 +729,27 @@ /* ** Return a pointer to static memory containing an SQL NULL value. */ static const Mem *columnNullValue(void){ /* Even though the Mem structure contains an element - ** of type i64, on certain architecture (x86) with certain compiler + ** of type i64, on certain architectures (x86) with certain compiler ** switches (-Os), gcc may align this Mem object on a 4-byte boundary ** instead of an 8-byte one. This all works fine, except that when ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s ** that a Mem structure is located on an 8-byte boundary. To prevent - ** this assert() from failing, when building with SQLITE_DEBUG defined - ** using gcc, force nullMem to be 8-byte aligned using the magical + ** these assert()s from failing, when building with SQLITE_DEBUG defined + ** using gcc, we force nullMem to be 8-byte aligned using the magical ** __attribute__((aligned(8))) macro. */ static const Mem nullMem #if defined(SQLITE_DEBUG) && defined(__GNUC__) - __attribute__((aligned(8))) + __attribute__((aligned(8))) +#endif + = {0, "", (double)0, {0}, 0, MEM_Null, 0, +#ifdef SQLITE_DEBUG + 0, 0, /* pScopyFrom, pFiller */ #endif - = {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0, 0, 0 }; + 0, 0 }; return &nullMem; } /* ** Check to see if column iCol of the given statement is valid. If @@ -1418,11 +1421,10 @@ }else{ *ppValue = &p->pUnpacked->aMem[iIdx]; if( iIdx==p->iPKey ){ sqlite3VdbeMemSetInt64(*ppValue, p->iKey1); } - sqlite3VdbeMemStoreType(*ppValue); } preupdate_old_out: sqlite3Error(db, rc, 0); return sqlite3ApiExit(db, rc); @@ -1497,11 +1499,10 @@ }else{ pMem = &pUnpack->aMem[iIdx]; if( iIdx==p->iPKey ){ sqlite3VdbeMemSetInt64(pMem, p->iKey2); } - sqlite3VdbeMemStoreType(pMem); } }else{ /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required ** value. Make a copy of the cell contents and return a pointer to it. ** It is not safe to return a pointer to the memory cell itself as the @@ -1522,15 +1523,14 @@ sqlite3VdbeMemSetInt64(pMem, p->iKey2); }else{ rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]); if( rc!=SQLITE_OK ) goto preupdate_new_out; } - sqlite3VdbeMemStoreType(pMem); } } *ppValue = pMem; preupdate_new_out: sqlite3Error(db, rc, 0); return sqlite3ApiExit(db, rc); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ Index: src/vdbeaux.c ================================================================== --- src/vdbeaux.c +++ src/vdbeaux.c @@ -1362,19 +1362,17 @@ } pOp = &apSub[j]->aOp[i]; } if( p->explain==1 ){ pMem->flags = MEM_Int; - pMem->memType = MEM_Int; pMem->u.i = i; /* Program counter */ pMem++; pMem->flags = MEM_Static|MEM_Str|MEM_Term; pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */ assert( pMem->z!=0 ); pMem->n = sqlite3Strlen30(pMem->z); - pMem->memType = MEM_Str; pMem->enc = SQLITE_UTF8; pMem++; /* When an OP_Program opcode is encounter (the only opcode that has ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms @@ -1396,21 +1394,18 @@ } } pMem->flags = MEM_Int; pMem->u.i = pOp->p1; /* P1 */ - pMem->memType = MEM_Int; pMem++; pMem->flags = MEM_Int; pMem->u.i = pOp->p2; /* P2 */ - pMem->memType = MEM_Int; pMem++; pMem->flags = MEM_Int; pMem->u.i = pOp->p3; /* P3 */ - pMem->memType = MEM_Int; pMem++; if( sqlite3VdbeMemGrow(pMem, 32, 0) ){ /* P4 */ assert( p->db->mallocFailed ); return SQLITE_ERROR; @@ -1422,11 +1417,10 @@ }else{ assert( pMem->z!=0 ); pMem->n = sqlite3Strlen30(pMem->z); pMem->enc = SQLITE_UTF8; } - pMem->memType = MEM_Str; pMem++; if( p->explain==1 ){ if( sqlite3VdbeMemGrow(pMem, 4, 0) ){ assert( p->db->mallocFailed ); @@ -1433,11 +1427,10 @@ return SQLITE_ERROR; } pMem->flags = MEM_Str|MEM_Term; pMem->n = 2; sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */ - pMem->memType = MEM_Str; pMem->enc = SQLITE_UTF8; pMem++; #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS if( sqlite3VdbeMemGrow(pMem, 500, 0) ){ @@ -1444,15 +1437,13 @@ assert( p->db->mallocFailed ); return SQLITE_ERROR; } pMem->flags = MEM_Str|MEM_Term; pMem->n = displayComment(pOp, zP4, pMem->z, 500); - pMem->memType = MEM_Str; pMem->enc = SQLITE_UTF8; #else pMem->flags = MEM_Null; /* Comment */ - pMem->memType = MEM_Null; #endif } p->nResColumn = 8 - 4*(p->explain-1); p->pResultSet = &p->aMem[1]; @@ -3539,13 +3530,14 @@ if( rc!=0 ){ if( pKeyInfo->aSortOrder[i] ){ rc = -rc; } - assert( CORRUPT_DB + assert( CORRUPT_DB || (rc<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0) || (rc>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0) + || pKeyInfo->db->mallocFailed ); assert( mem1.zMalloc==0 ); /* See comment below */ return rc; } @@ -3936,11 +3928,10 @@ if( 0==(pMem->flags & MEM_Null) ){ sqlite3_value *pRet = sqlite3ValueNew(v->db); if( pRet ){ sqlite3VdbeMemCopy((Mem *)pRet, pMem); sqlite3ValueApplyAffinity(pRet, aff, SQLITE_UTF8); - sqlite3VdbeMemStoreType((Mem *)pRet); } return pRet; } } return 0; Index: src/vdbemem.c ================================================================== --- src/vdbemem.c +++ src/vdbemem.c @@ -120,10 +120,11 @@ sqlite3DbFree(pMem->db, pMem->zMalloc); pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); } if( pMem->zMalloc==0 ){ VdbeMemRelease(pMem); + pMem->z = 0; pMem->flags = MEM_Null; return SQLITE_NOMEM; } } @@ -318,11 +319,11 @@ } /* ** Release any memory held by the Mem. This may leave the Mem in an ** inconsistent state, for example with (Mem.z==0) and -** (Mem.memType==MEM_Str). +** (Mem.flags==MEM_Str). */ void sqlite3VdbeMemRelease(Mem *p){ assert( sqlite3VdbeCheckMemInvariants(p) ); VdbeMemRelease(p); if( p->zMalloc ){ @@ -510,11 +511,10 @@ } if( pMem->flags & MEM_RowSet ){ sqlite3RowSetClear(pMem->u.pRowSet); } MemSetTypeFlag(pMem, MEM_Null); - pMem->memType = MEM_Null; } void sqlite3ValueSetNull(sqlite3_value *p){ sqlite3VdbeMemSetNull((Mem*)p); } @@ -523,11 +523,10 @@ ** n containing all zeros. */ void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ sqlite3VdbeMemRelease(pMem); pMem->flags = MEM_Blob|MEM_Zero; - pMem->memType = MEM_Blob; pMem->n = 0; if( n<0 ) n = 0; pMem->u.nZero = n; pMem->enc = SQLITE_UTF8; @@ -546,11 +545,10 @@ */ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ sqlite3VdbeMemRelease(pMem); pMem->u.i = val; pMem->flags = MEM_Int; - pMem->memType = MEM_Int; } #ifndef SQLITE_OMIT_FLOATING_POINT /* ** Delete any previous value and set the value stored in *pMem to val, @@ -561,11 +559,10 @@ sqlite3VdbeMemSetNull(pMem); }else{ sqlite3VdbeMemRelease(pMem); pMem->r = val; pMem->flags = MEM_Real; - pMem->memType = MEM_Real; } } #endif /* @@ -770,11 +767,10 @@ } pMem->n = nByte; pMem->flags = flags; pMem->enc = (enc==0 ? SQLITE_UTF8 : enc); - pMem->memType = flags&0x1f; #ifndef SQLITE_OMIT_UTF16 if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ return SQLITE_NOMEM; } @@ -836,11 +832,10 @@ } if( rc==SQLITE_OK ){ pMem->z[amt] = 0; pMem->z[amt+1] = 0; pMem->flags = MEM_Blob|MEM_Term; - pMem->memType = MEM_Blob; pMem->n = (int)amt; }else{ sqlite3VdbeMemRelease(pMem); } } @@ -899,11 +894,10 @@ */ sqlite3_value *sqlite3ValueNew(sqlite3 *db){ Mem *p = sqlite3DbMallocZero(db, sizeof(*p)); if( p ){ p->flags = MEM_Null; - p->memType = MEM_Null; p->db = db; } return p; } @@ -948,11 +942,10 @@ assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol ); assert( pRec->pKeyInfo->enc==ENC(db) ); pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord))); for(i=0; iaMem[i].flags = MEM_Null; - pRec->aMem[i].memType = MEM_Null; pRec->aMem[i].db = db; } }else{ sqlite3DbFree(db, pRec); pRec = 0; @@ -1021,11 +1014,10 @@ sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); }else{ zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); if( zVal==0 ) goto no_mem; sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); - if( op==TK_FLOAT ) pVal->memType = MEM_Real; } if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){ sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); }else{ sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); @@ -1039,13 +1031,13 @@ if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) && pVal!=0 ){ sqlite3VdbeMemNumerify(pVal); if( pVal->u.i==SMALLEST_INT64 ){ - pVal->flags &= MEM_Int; + pVal->flags &= ~MEM_Int; pVal->flags |= MEM_Real; - pVal->r = (double)LARGEST_INT64; + pVal->r = (double)SMALLEST_INT64; }else{ pVal->u.i = -pVal->u.i; } pVal->r = -pVal->r; sqlite3ValueApplyAffinity(pVal, affinity, enc); @@ -1067,13 +1059,10 @@ sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2, 0, SQLITE_DYNAMIC); } #endif - if( pVal ){ - sqlite3VdbeMemStoreType(pVal); - } *ppVal = pVal; return rc; no_mem: db->mallocFailed = 1; @@ -1233,11 +1222,10 @@ rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]); if( rc==SQLITE_OK ){ sqlite3ValueApplyAffinity(pVal, affinity, ENC(db)); } pVal->db = pParse->db; - sqlite3VdbeMemStoreType((Mem*)pVal); } } }else{ rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, &alloc); } Index: test/alter4.test ================================================================== --- test/alter4.test +++ test/alter4.test @@ -332,6 +332,27 @@ execsql { SELECT sql FROM sqlite_temp_master WHERE name = 't4'; } } [list $::sql] + +# Test that a default value equal to -1 multipied by the smallest possible +# 64-bit integer is correctly converted to a real. +do_execsql_test alter4-9.1 { + CREATE TABLE t5( + a INTEGER DEFAULT -9223372036854775808, + b INTEGER DEFAULT (-(-9223372036854775808)) + ); + INSERT INTO t5 DEFAULT VALUES; +} + +do_execsql_test alter4-9.2 { SELECT typeof(a), a, typeof(b), b FROM t5; } { + integer -9223372036854775808 + real 9.22337203685478e+18 +} + +do_execsql_test alter4-9.3 { + ALTER TABLE t5 ADD COLUMN c INTEGER DEFAULT (-(-9223372036854775808)); + SELECT typeof(c), c FROM t5; +} {real 9.22337203685478e+18} + finish_test Index: test/corruptI.test ================================================================== --- test/corruptI.test +++ test/corruptI.test @@ -11,10 +11,15 @@ # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix corruptI + +if {[permutation]=="mmap"} { + finish_test + return +} # Do not use a codec for tests in this file, as the database file is # manipulated directly using tcl scripts (using the [hexio_write] command). # do_not_use_codec Index: test/view.test ================================================================== --- test/view.test +++ test/view.test @@ -608,7 +608,20 @@ catchsql { SELECT * FROM v32768; } } {1 interrupted} } + +db close +sqlite3 db :memory: +do_execsql_test view-22.1 { + CREATE VIEW x1 AS SELECT 123 AS '', 234 AS '', 345 AS ''; + SELECT * FROM x1; +} {123 234 345} +do_test view-22.2 { + unset -nocomplain x + db eval {SELECT * FROM x1} x break + lsort [array names x] +} {{} * :1 :2} + finish_test