| Index: third_party/sqlite/sqlite-src-3100200/src/vdbemem.c
|
| diff --git a/third_party/sqlite/sqlite-src-3080704/src/vdbemem.c b/third_party/sqlite/sqlite-src-3100200/src/vdbemem.c
|
| similarity index 88%
|
| copy from third_party/sqlite/sqlite-src-3080704/src/vdbemem.c
|
| copy to third_party/sqlite/sqlite-src-3100200/src/vdbemem.c
|
| index 870fb5bd891c2c83ae8c8683afa5ceca93b99649..fae69b18a4f1810092a436c44fa19b8b31ad3e6a 100644
|
| --- a/third_party/sqlite/sqlite-src-3080704/src/vdbemem.c
|
| +++ b/third_party/sqlite/sqlite-src-3100200/src/vdbemem.c
|
| @@ -200,10 +200,11 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){
|
| pMem->z[pMem->n] = 0;
|
| pMem->z[pMem->n+1] = 0;
|
| pMem->flags |= MEM_Term;
|
| + }
|
| + pMem->flags &= ~MEM_Ephem;
|
| #ifdef SQLITE_DEBUG
|
| - pMem->pScopyFrom = 0;
|
| + pMem->pScopyFrom = 0;
|
| #endif
|
| - }
|
|
|
| return SQLITE_OK;
|
| }
|
| @@ -587,7 +588,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){
|
| void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
|
| if( pMem->flags & MEM_Null ) return;
|
| switch( aff ){
|
| - case SQLITE_AFF_NONE: { /* Really a cast to BLOB */
|
| + case SQLITE_AFF_BLOB: { /* Really a cast to BLOB */
|
| if( (pMem->flags & MEM_Blob)==0 ){
|
| sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
|
| assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
|
| @@ -769,10 +770,6 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
|
| }
|
| #endif /* SQLITE_DEBUG */
|
|
|
| -/*
|
| -** Size of struct Mem not including the Mem.zMalloc member.
|
| -*/
|
| -#define MEMCELLSIZE offsetof(Mem,zMalloc)
|
|
|
| /*
|
| ** Make an shallow copy of pFrom into pTo. Prior contents of
|
| @@ -780,10 +777,15 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
|
| ** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
|
| ** and flags gets srcType (either MEM_Ephem or MEM_Static).
|
| */
|
| +static SQLITE_NOINLINE void vdbeClrCopy(Mem *pTo, const Mem *pFrom, int eType){
|
| + vdbeMemClearExternAndSetNull(pTo);
|
| + assert( !VdbeMemDynamic(pTo) );
|
| + sqlite3VdbeMemShallowCopy(pTo, pFrom, eType);
|
| +}
|
| void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
|
| assert( (pFrom->flags & MEM_RowSet)==0 );
|
| assert( pTo->db==pFrom->db );
|
| - if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
|
| + if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; }
|
| memcpy(pTo, pFrom, MEMCELLSIZE);
|
| if( (pFrom->flags&MEM_Static)==0 ){
|
| pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
|
| @@ -799,7 +801,10 @@ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
|
| int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
|
| int rc = SQLITE_OK;
|
|
|
| - assert( pTo->db==pFrom->db );
|
| + /* The pFrom==0 case in the following assert() is when an sqlite3_value
|
| + ** from sqlite3_value_dup() is used as the argument
|
| + ** to sqlite3_result_value(). */
|
| + assert( pTo->db==pFrom->db || pFrom->db==0 );
|
| assert( (pFrom->flags & MEM_RowSet)==0 );
|
| if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
|
| memcpy(pTo, pFrom, MEMCELLSIZE);
|
| @@ -946,6 +951,32 @@ int sqlite3VdbeMemSetStr(
|
| ** If this routine fails for any reason (malloc returns NULL or unable
|
| ** to read from the disk) then the pMem is left in an inconsistent state.
|
| */
|
| +static SQLITE_NOINLINE int vdbeMemFromBtreeResize(
|
| + BtCursor *pCur, /* Cursor pointing at record to retrieve. */
|
| + u32 offset, /* Offset from the start of data to return bytes from. */
|
| + u32 amt, /* Number of bytes to return. */
|
| + int key, /* If true, retrieve from the btree key, not data. */
|
| + Mem *pMem /* OUT: Return data in this Mem structure. */
|
| +){
|
| + int rc;
|
| + pMem->flags = MEM_Null;
|
| + if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){
|
| + if( key ){
|
| + rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
|
| + }else{
|
| + rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
|
| + }
|
| + if( rc==SQLITE_OK ){
|
| + pMem->z[amt] = 0;
|
| + pMem->z[amt+1] = 0;
|
| + pMem->flags = MEM_Blob|MEM_Term;
|
| + pMem->n = (int)amt;
|
| + }else{
|
| + sqlite3VdbeMemRelease(pMem);
|
| + }
|
| + }
|
| + return rc;
|
| +}
|
| int sqlite3VdbeMemFromBtree(
|
| BtCursor *pCur, /* Cursor pointing at record to retrieve. */
|
| u32 offset, /* Offset from the start of data to return bytes from. */
|
| @@ -975,22 +1006,7 @@ int sqlite3VdbeMemFromBtree(
|
| pMem->flags = MEM_Blob|MEM_Ephem;
|
| pMem->n = (int)amt;
|
| }else{
|
| - pMem->flags = MEM_Null;
|
| - if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){
|
| - if( key ){
|
| - rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
|
| - }else{
|
| - rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
|
| - }
|
| - if( rc==SQLITE_OK ){
|
| - pMem->z[amt] = 0;
|
| - pMem->z[amt+1] = 0;
|
| - pMem->flags = MEM_Blob|MEM_Term;
|
| - pMem->n = (int)amt;
|
| - }else{
|
| - sqlite3VdbeMemRelease(pMem);
|
| - }
|
| - }
|
| + rc = vdbeMemFromBtreeResize(pCur, offset, amt, key, pMem);
|
| }
|
|
|
| return rc;
|
| @@ -1090,7 +1106,7 @@ struct ValueNewStat4Ctx {
|
| ** Otherwise, if the second argument is non-zero, then this function is
|
| ** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not
|
| ** already been allocated, allocate the UnpackedRecord structure that
|
| -** that function will return to its caller here. Then return a pointer
|
| +** that function will return to its caller here. Then return a pointer to
|
| ** an sqlite3_value within the UnpackedRecord.a[] array.
|
| */
|
| static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
|
| @@ -1135,6 +1151,113 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
|
| }
|
|
|
| /*
|
| +** The expression object indicated by the second argument is guaranteed
|
| +** to be a scalar SQL function. If
|
| +**
|
| +** * all function arguments are SQL literals,
|
| +** * one of the SQLITE_FUNC_CONSTANT or _SLOCHNG function flags is set, and
|
| +** * the SQLITE_FUNC_NEEDCOLL function flag is not set,
|
| +**
|
| +** then this routine attempts to invoke the SQL function. Assuming no
|
| +** error occurs, output parameter (*ppVal) is set to point to a value
|
| +** object containing the result before returning SQLITE_OK.
|
| +**
|
| +** Affinity aff is applied to the result of the function before returning.
|
| +** If the result is a text value, the sqlite3_value object uses encoding
|
| +** enc.
|
| +**
|
| +** If the conditions above are not met, this function returns SQLITE_OK
|
| +** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to
|
| +** NULL and an SQLite error code returned.
|
| +*/
|
| +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
| +static int valueFromFunction(
|
| + sqlite3 *db, /* The database connection */
|
| + Expr *p, /* The expression to evaluate */
|
| + u8 enc, /* Encoding to use */
|
| + u8 aff, /* Affinity to use */
|
| + sqlite3_value **ppVal, /* Write the new value here */
|
| + struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */
|
| +){
|
| + sqlite3_context ctx; /* Context object for function invocation */
|
| + sqlite3_value **apVal = 0; /* Function arguments */
|
| + int nVal = 0; /* Size of apVal[] array */
|
| + FuncDef *pFunc = 0; /* Function definition */
|
| + sqlite3_value *pVal = 0; /* New value */
|
| + int rc = SQLITE_OK; /* Return code */
|
| + int nName; /* Size of function name in bytes */
|
| + ExprList *pList = 0; /* Function arguments */
|
| + int i; /* Iterator variable */
|
| +
|
| + assert( pCtx!=0 );
|
| + assert( (p->flags & EP_TokenOnly)==0 );
|
| + pList = p->x.pList;
|
| + if( pList ) nVal = pList->nExpr;
|
| + nName = sqlite3Strlen30(p->u.zToken);
|
| + pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0);
|
| + assert( pFunc );
|
| + if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
|
| + || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
|
| + ){
|
| + return SQLITE_OK;
|
| + }
|
| +
|
| + if( pList ){
|
| + apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal);
|
| + if( apVal==0 ){
|
| + rc = SQLITE_NOMEM;
|
| + goto value_from_function_out;
|
| + }
|
| + for(i=0; i<nVal; i++){
|
| + rc = sqlite3ValueFromExpr(db, pList->a[i].pExpr, enc, aff, &apVal[i]);
|
| + if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out;
|
| + }
|
| + }
|
| +
|
| + pVal = valueNew(db, pCtx);
|
| + if( pVal==0 ){
|
| + rc = SQLITE_NOMEM;
|
| + goto value_from_function_out;
|
| + }
|
| +
|
| + assert( pCtx->pParse->rc==SQLITE_OK );
|
| + memset(&ctx, 0, sizeof(ctx));
|
| + ctx.pOut = pVal;
|
| + ctx.pFunc = pFunc;
|
| + pFunc->xFunc(&ctx, nVal, apVal);
|
| + if( ctx.isError ){
|
| + rc = ctx.isError;
|
| + sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal));
|
| + }else{
|
| + sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8);
|
| + assert( rc==SQLITE_OK );
|
| + rc = sqlite3VdbeChangeEncoding(pVal, enc);
|
| + if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){
|
| + rc = SQLITE_TOOBIG;
|
| + pCtx->pParse->nErr++;
|
| + }
|
| + }
|
| + pCtx->pParse->rc = rc;
|
| +
|
| + value_from_function_out:
|
| + if( rc!=SQLITE_OK ){
|
| + pVal = 0;
|
| + }
|
| + if( apVal ){
|
| + for(i=0; i<nVal; i++){
|
| + sqlite3ValueFree(apVal[i]);
|
| + }
|
| + sqlite3DbFree(db, apVal);
|
| + }
|
| +
|
| + *ppVal = pVal;
|
| + return rc;
|
| +}
|
| +#else
|
| +# define valueFromFunction(a,b,c,d,e,f) SQLITE_OK
|
| +#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */
|
| +
|
| +/*
|
| ** Extract a value from the supplied expression in the manner described
|
| ** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object
|
| ** using valueNew().
|
| @@ -1166,6 +1289,12 @@ static int valueFromExpr(
|
| while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft;
|
| if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
|
|
|
| + /* Compressed expressions only appear when parsing the DEFAULT clause
|
| + ** on a table column definition, and hence only when pCtx==0. This
|
| + ** check ensures that an EP_TokenOnly expression is never passed down
|
| + ** into valueFromFunction(). */
|
| + assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 );
|
| +
|
| if( op==TK_CAST ){
|
| u8 aff = sqlite3AffinityType(pExpr->u.zToken,0);
|
| rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
|
| @@ -1198,7 +1327,7 @@ static int valueFromExpr(
|
| if( zVal==0 ) goto no_mem;
|
| sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
|
| }
|
| - if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
|
| + if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){
|
| sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
|
| }else{
|
| sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
|
| @@ -1242,6 +1371,12 @@ static int valueFromExpr(
|
| }
|
| #endif
|
|
|
| +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
| + else if( op==TK_FUNCTION && pCtx!=0 ){
|
| + rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
|
| + }
|
| +#endif
|
| +
|
| *ppVal = pVal;
|
| return rc;
|
|
|
| @@ -1292,17 +1427,16 @@ static void recordFunc(
|
| sqlite3_value **argv
|
| ){
|
| const int file_format = 1;
|
| - int iSerial; /* Serial type */
|
| + u32 iSerial; /* Serial type */
|
| int nSerial; /* Bytes of space for iSerial as varint */
|
| - int nVal; /* Bytes of space required for argv[0] */
|
| + u32 nVal; /* Bytes of space required for argv[0] */
|
| int nRet;
|
| sqlite3 *db;
|
| u8 *aRet;
|
|
|
| UNUSED_PARAMETER( argc );
|
| - iSerial = sqlite3VdbeSerialType(argv[0], file_format);
|
| + iSerial = sqlite3VdbeSerialType(argv[0], file_format, &nVal);
|
| nSerial = sqlite3VarintLen(iSerial);
|
| - nVal = sqlite3VdbeSerialTypeLen(iSerial);
|
| db = sqlite3_context_db_handle(context);
|
|
|
| nRet = 1 + nSerial + nVal;
|
| @@ -1528,7 +1662,7 @@ void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
|
| Mem *aMem = pRec->aMem;
|
| sqlite3 *db = aMem[0].db;
|
| for(i=0; i<nCol; i++){
|
| - if( aMem[i].szMalloc ) sqlite3DbFree(db, aMem[i].zMalloc);
|
| + sqlite3VdbeMemRelease(&aMem[i]);
|
| }
|
| sqlite3KeyInfoUnref(pRec->pKeyInfo);
|
| sqlite3DbFree(db, pRec);
|
| @@ -1559,17 +1693,26 @@ void sqlite3ValueFree(sqlite3_value *v){
|
| }
|
|
|
| /*
|
| -** Return the number of bytes in the sqlite3_value object assuming
|
| -** that it uses the encoding "enc"
|
| +** The sqlite3ValueBytes() routine returns the number of bytes in the
|
| +** sqlite3_value object assuming that it uses the encoding "enc".
|
| +** The valueBytes() routine is a helper function.
|
| */
|
| +static SQLITE_NOINLINE int valueBytes(sqlite3_value *pVal, u8 enc){
|
| + return valueToText(pVal, enc)!=0 ? pVal->n : 0;
|
| +}
|
| int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
|
| Mem *p = (Mem*)pVal;
|
| - if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){
|
| + assert( (p->flags & MEM_Null)==0 || (p->flags & (MEM_Str|MEM_Blob))==0 );
|
| + if( (p->flags & MEM_Str)!=0 && pVal->enc==enc ){
|
| + return p->n;
|
| + }
|
| + if( (p->flags & MEM_Blob)!=0 ){
|
| if( p->flags & MEM_Zero ){
|
| return p->n + p->u.nZero;
|
| }else{
|
| return p->n;
|
| }
|
| }
|
| - return 0;
|
| + if( p->flags & MEM_Null ) return 0;
|
| + return valueBytes(pVal, enc);
|
| }
|
|
|