diff options
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/vdbemem.c')
| -rw-r--r-- | ext/pdo_sqlite/sqlite/src/vdbemem.c | 149 |
1 files changed, 108 insertions, 41 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/vdbemem.c b/ext/pdo_sqlite/sqlite/src/vdbemem.c index 0b7e193bec..51cd6827fa 100644 --- a/ext/pdo_sqlite/sqlite/src/vdbemem.c +++ b/ext/pdo_sqlite/sqlite/src/vdbemem.c @@ -41,11 +41,22 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ #ifdef SQLITE_OMIT_UTF16 return SQLITE_ERROR; #else + + + /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned, + ** then the encoding of the value may not have changed. + */ rc = sqlite3VdbeMemTranslate(pMem, desiredEnc); + assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); + assert(rc==SQLITE_OK || pMem->enc!=desiredEnc); + assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc); + if( rc==SQLITE_NOMEM ){ +/* sqlite3VdbeMemRelease(pMem); pMem->flags = MEM_Null; pMem->z = 0; +*/ } return rc; #endif @@ -73,7 +84,7 @@ int sqlite3VdbeMemDynamicify(Mem *pMem){ memcpy(z, pMem->z, n ); z[n] = 0; z[n+1] = 0; - pMem->z = z; + pMem->z = (char*)z; pMem->flags &= ~(MEM_Ephem|MEM_Static|MEM_Short); return SQLITE_OK; } @@ -93,7 +104,7 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){ assert( (pMem->flags & MEM_Dyn)==0 ); assert( pMem->flags & (MEM_Str|MEM_Blob) ); if( (n = pMem->n)+2<sizeof(pMem->zShort) ){ - z = pMem->zShort; + z = (u8*)pMem->zShort; pMem->flags |= MEM_Short|MEM_Term; }else{ z = sqliteMallocRaw( n+2 ); @@ -106,8 +117,9 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){ memcpy(z, pMem->z, n ); z[n] = 0; z[n+1] = 0; - pMem->z = z; + pMem->z = (char*)z; pMem->flags &= ~(MEM_Ephem|MEM_Static); + assert(0==(1&(int)pMem->z)); return SQLITE_OK; } @@ -162,7 +174,7 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){ int sqlite3VdbeMemStringify(Mem *pMem, int enc){ int rc = SQLITE_OK; int fg = pMem->flags; - u8 *z = pMem->zShort; + char *z = pMem->zShort; assert( !(fg&(MEM_Str|MEM_Blob)) ); assert( fg&(MEM_Int|MEM_Real) ); @@ -173,11 +185,11 @@ int sqlite3VdbeMemStringify(Mem *pMem, int enc){ ** ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16. */ - if( fg & MEM_Real ){ - sqlite3_snprintf(NBFS, z, "%!.15g", pMem->r); - }else{ - assert( fg & MEM_Int ); + if( fg & MEM_Int ){ sqlite3_snprintf(NBFS, z, "%lld", pMem->i); + }else{ + assert( fg & MEM_Real ); + sqlite3_snprintf(NBFS, z, "%!.15g", pMem->r); } pMem->n = strlen(z); pMem->z = z; @@ -191,8 +203,12 @@ int sqlite3VdbeMemStringify(Mem *pMem, int enc){ ** Memory cell pMem contains the context of an aggregate function. ** This routine calls the finalize method for that function. The ** result of the aggregate is stored back into pMem. +** +** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK +** otherwise. */ -void sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ +int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ + int rc = SQLITE_OK; if( pFunc && pFunc->xFinalize ){ sqlite3_context ctx; assert( (pMem->flags & MEM_Null)!=0 || pFunc==*(FuncDef**)&pMem->i ); @@ -200,6 +216,7 @@ void sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ ctx.s.z = pMem->zShort; ctx.pMem = pMem; ctx.pFunc = pFunc; + ctx.isError = 0; pFunc->xFinalize(&ctx); if( pMem->z && pMem->z!=pMem->zShort ){ sqliteFree( pMem->z ); @@ -208,7 +225,11 @@ void sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ if( pMem->flags & MEM_Short ){ pMem->z = pMem->zShort; } + if( ctx.isError ){ + rc = SQLITE_ERROR; + } } + return rc; } /* @@ -254,7 +275,7 @@ i64 sqlite3VdbeIntValue(Mem *pMem){ i64 value; if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8) || sqlite3VdbeMemNulTerminate(pMem) ){ - return SQLITE_NOMEM; + return 0; } assert( pMem->z ); sqlite3atoi64(pMem->z, &value); @@ -265,16 +286,6 @@ i64 sqlite3VdbeIntValue(Mem *pMem){ } /* -** Convert pMem to type integer. Invalidate any prior representations. -*/ -int sqlite3VdbeMemIntegerify(Mem *pMem){ - pMem->i = sqlite3VdbeIntValue(pMem); - sqlite3VdbeMemRelease(pMem); - pMem->flags = MEM_Int; - return SQLITE_OK; -} - -/* ** Return the best representation of pMem that we can get into a ** double. If pMem is already a double or an integer, return its ** value. If it is a string or blob, try to convert it to a double. @@ -289,7 +300,7 @@ double sqlite3VdbeRealValue(Mem *pMem){ double val = 0.0; if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8) || sqlite3VdbeMemNulTerminate(pMem) ){ - return SQLITE_NOMEM; + return 0.0; } assert( pMem->z ); sqlite3AtoF(pMem->z, &val); @@ -300,8 +311,30 @@ double sqlite3VdbeRealValue(Mem *pMem){ } /* -** Convert pMem so that it is of type MEM_Real. Invalidate any -** prior representations. +** The MEM structure is already a MEM_Real. Try to also make it a +** MEM_Int if we can. +*/ +void sqlite3VdbeIntegerAffinity(Mem *pMem){ + assert( pMem->flags & MEM_Real ); + pMem->i = pMem->r; + if( ((double)pMem->i)==pMem->r ){ + pMem->flags |= MEM_Int; + } +} + +/* +** Convert pMem to type integer. Invalidate any prior representations. +*/ +int sqlite3VdbeMemIntegerify(Mem *pMem){ + pMem->i = sqlite3VdbeIntValue(pMem); + sqlite3VdbeMemRelease(pMem); + pMem->flags = MEM_Int; + return SQLITE_OK; +} + +/* +** Convert pMem so that it is of type MEM_Real. +** Invalidate any prior representations. */ int sqlite3VdbeMemRealify(Mem *pMem){ pMem->r = sqlite3VdbeRealValue(pMem); @@ -311,6 +344,16 @@ int sqlite3VdbeMemRealify(Mem *pMem){ } /* +** Convert pMem so that it has types MEM_Real or MEM_Int or both. +** Invalidate any prior representations. +*/ +int sqlite3VdbeMemNumerify(Mem *pMem){ + sqlite3VdbeMemRealify(pMem); + sqlite3VdbeIntegerAffinity(pMem); + return SQLITE_OK; +} + +/* ** Delete any previous value and set the value stored in *pMem to NULL. */ void sqlite3VdbeMemSetNull(Mem *pMem){ @@ -547,27 +590,33 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ assert( pMem1->enc==SQLITE_UTF8 || pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE ); - /* This assert may fail if the collation sequence is deleted after this - ** vdbe program is compiled. The documentation defines this as an - ** undefined condition. A crash is usual result. + /* The collation sequence must be defined at this point, even if + ** the user deletes the collation sequence after the vdbe program is + ** compiled (this was not always the case). */ assert( !pColl || pColl->xCmp ); if( pColl ){ if( pMem1->enc==pColl->enc ){ + /* The strings are already in the correct encoding. Call the + ** comparison function directly */ return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z); }else{ u8 origEnc = pMem1->enc; - rc = pColl->xCmp( - pColl->pUser, - sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc), - sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc), - sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc), - sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc) - ); - sqlite3ValueBytes((sqlite3_value*)pMem1, origEnc); + const void *v1, *v2; + int n1, n2; + /* Convert the strings into the encoding that the comparison + ** function expects */ + v1 = sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc); + n1 = v1==0 ? 0 : pMem1->n; + assert( n1==sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc) ); + v2 = sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc); + n2 = v2==0 ? 0 : pMem2->n; + assert( n2==sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc) ); + /* Do the comparison */ + rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2); + /* Convert the strings back into the database encoding */ sqlite3ValueText((sqlite3_value*)pMem1, origEnc); - sqlite3ValueBytes((sqlite3_value*)pMem2, origEnc); sqlite3ValueText((sqlite3_value*)pMem2, origEnc); return rc; } @@ -662,7 +711,7 @@ int sqlite3VdbeMemFromBtree( ** Perform various checks on the memory cell pMem. An assert() will ** fail if pMem is internally inconsistent. */ -void sqlite3VdbeMemSanity(Mem *pMem, u8 db_enc){ +void sqlite3VdbeMemSanity(Mem *pMem){ int flags = pMem->flags; assert( flags!=0 ); /* Must define some type */ if( pMem->flags & (MEM_Str|MEM_Blob) ){ @@ -711,20 +760,38 @@ void sqlite3VdbeMemSanity(Mem *pMem, u8 db_enc){ ** except the data returned is in the encoding specified by the second ** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or ** SQLITE_UTF8. +** +** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED. +** If that is the case, then the result must be aligned on an even byte +** boundary. */ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ if( !pVal ) return 0; - assert( enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE || enc==SQLITE_UTF8); + assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); if( pVal->flags&MEM_Null ){ return 0; } + assert( (MEM_Blob>>3) == MEM_Str ); + pVal->flags |= (pVal->flags & MEM_Blob)>>3; if( pVal->flags&MEM_Str ){ - sqlite3VdbeChangeEncoding(pVal, enc); + sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); + if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(int)pVal->z) ){ + assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); + if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){ + return 0; + } + } }else if( !(pVal->flags&MEM_Blob) ){ sqlite3VdbeMemStringify(pVal, enc); + assert( 0==(1&(int)pVal->z) ); + } + assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || sqlite3MallocFailed() ); + if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ + return pVal->z; + }else{ + return 0; } - return (const void *)(pVal->z); } /* @@ -766,7 +833,7 @@ int sqlite3ValueFromExpr( op = pExpr->op; if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ - zVal = sqliteStrNDup(pExpr->token.z, pExpr->token.n); + zVal = sqliteStrNDup((char*)pExpr->token.z, pExpr->token.n); pVal = sqlite3ValueNew(); if( !zVal || !pVal ) goto no_mem; sqlite3Dequote(zVal); @@ -786,7 +853,7 @@ int sqlite3ValueFromExpr( else if( op==TK_BLOB ){ int nVal; pVal = sqlite3ValueNew(); - zVal = sqliteStrNDup(pExpr->token.z+1, pExpr->token.n-1); + zVal = sqliteStrNDup((char*)pExpr->token.z+1, pExpr->token.n-1); if( !zVal || !pVal ) goto no_mem; sqlite3Dequote(zVal); nVal = strlen(zVal)/2; |
