summaryrefslogtreecommitdiff
path: root/ext/pdo_sqlite/sqlite/src/vdbemem.c
diff options
context:
space:
mode:
authorIlia Alshanetsky <iliaa@php.net>2006-08-14 16:15:29 +0000
committerIlia Alshanetsky <iliaa@php.net>2006-08-14 16:15:29 +0000
commite8f30d450255baa92c1f2abe5d4a2696b6e4ebf0 (patch)
tree1ededffa0df99ad1b61a3e476febad54b6a15991 /ext/pdo_sqlite/sqlite/src/vdbemem.c
parent0091c7e1b337de1252824ec33c87b4bed9ca2a5c (diff)
downloadphp-git-e8f30d450255baa92c1f2abe5d4a2696b6e4ebf0.tar.gz
Upgraded bunbled SQLite lib to 3.3.7
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/vdbemem.c')
-rw-r--r--ext/pdo_sqlite/sqlite/src/vdbemem.c149
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;