Index: third_party/sqlite/src/src/vdbemem.c |
diff --git a/third_party/sqlite/src/src/vdbemem.c b/third_party/sqlite/src/src/vdbemem.c |
index fae69b18a4f1810092a436c44fa19b8b31ad3e6a..656e19bfa890a20b63c9710bb7bbd5a4fac565c2 100644 |
--- a/third_party/sqlite/src/src/vdbemem.c |
+++ b/third_party/sqlite/src/src/vdbemem.c |
@@ -116,6 +116,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ |
SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ |
assert( sqlite3VdbeCheckMemInvariants(pMem) ); |
assert( (pMem->flags&MEM_RowSet)==0 ); |
+ testcase( pMem->db==0 ); |
/* If the bPreserve flag is set to true, then the memory cell must already |
** contain a valid string or blob value. */ |
@@ -137,7 +138,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ |
sqlite3VdbeMemSetNull(pMem); |
pMem->z = 0; |
pMem->szMalloc = 0; |
- return SQLITE_NOMEM; |
+ return SQLITE_NOMEM_BKPT; |
}else{ |
pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); |
} |
@@ -188,18 +189,18 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ |
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. |
*/ |
int sqlite3VdbeMemMakeWriteable(Mem *pMem){ |
- int f; |
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
assert( (pMem->flags&MEM_RowSet)==0 ); |
- ExpandBlob(pMem); |
- f = pMem->flags; |
- if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || pMem->z!=pMem->zMalloc) ){ |
- if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){ |
- return SQLITE_NOMEM; |
+ if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){ |
+ if( ExpandBlob(pMem) ) return SQLITE_NOMEM; |
+ if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){ |
+ if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){ |
+ return SQLITE_NOMEM_BKPT; |
+ } |
+ pMem->z[pMem->n] = 0; |
+ pMem->z[pMem->n+1] = 0; |
+ pMem->flags |= MEM_Term; |
} |
- pMem->z[pMem->n] = 0; |
- pMem->z[pMem->n+1] = 0; |
- pMem->flags |= MEM_Term; |
} |
pMem->flags &= ~MEM_Ephem; |
#ifdef SQLITE_DEBUG |
@@ -215,25 +216,24 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){ |
*/ |
#ifndef SQLITE_OMIT_INCRBLOB |
int sqlite3VdbeMemExpandBlob(Mem *pMem){ |
- if( pMem->flags & MEM_Zero ){ |
- int nByte; |
- assert( pMem->flags&MEM_Blob ); |
- assert( (pMem->flags&MEM_RowSet)==0 ); |
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
- |
- /* Set nByte to the number of bytes required to store the expanded blob. */ |
- nByte = pMem->n + pMem->u.nZero; |
- if( nByte<=0 ){ |
- nByte = 1; |
- } |
- if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){ |
- return SQLITE_NOMEM; |
- } |
+ int nByte; |
+ assert( pMem->flags & MEM_Zero ); |
+ assert( pMem->flags&MEM_Blob ); |
+ assert( (pMem->flags&MEM_RowSet)==0 ); |
+ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
- memset(&pMem->z[pMem->n], 0, pMem->u.nZero); |
- pMem->n += pMem->u.nZero; |
- pMem->flags &= ~(MEM_Zero|MEM_Term); |
+ /* Set nByte to the number of bytes required to store the expanded blob. */ |
+ nByte = pMem->n + pMem->u.nZero; |
+ if( nByte<=0 ){ |
+ nByte = 1; |
} |
+ if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){ |
+ return SQLITE_NOMEM_BKPT; |
+ } |
+ |
+ memset(&pMem->z[pMem->n], 0, pMem->u.nZero); |
+ pMem->n += pMem->u.nZero; |
+ pMem->flags &= ~(MEM_Zero|MEM_Term); |
return SQLITE_OK; |
} |
#endif |
@@ -244,7 +244,7 @@ int sqlite3VdbeMemExpandBlob(Mem *pMem){ |
*/ |
static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ |
if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){ |
- return SQLITE_NOMEM; |
+ return SQLITE_NOMEM_BKPT; |
} |
pMem->z[pMem->n] = 0; |
pMem->z[pMem->n+1] = 0; |
@@ -293,7 +293,8 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ |
if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){ |
- return SQLITE_NOMEM; |
+ pMem->enc = 0; |
+ return SQLITE_NOMEM_BKPT; |
} |
/* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8 |
@@ -574,7 +575,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){ |
} |
} |
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 ); |
- pMem->flags &= ~(MEM_Str|MEM_Blob); |
+ pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero); |
return SQLITE_OK; |
} |
@@ -592,7 +593,7 @@ void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ |
if( (pMem->flags & MEM_Blob)==0 ){ |
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); |
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); |
- MemSetTypeFlag(pMem, MEM_Blob); |
+ if( pMem->flags & MEM_Str ) MemSetTypeFlag(pMem, MEM_Blob); |
}else{ |
pMem->flags &= ~(MEM_TypeMask&~MEM_Blob); |
} |
@@ -719,7 +720,7 @@ void sqlite3VdbeMemSetRowSet(Mem *pMem){ |
assert( db!=0 ); |
assert( (pMem->flags & MEM_RowSet)==0 ); |
sqlite3VdbeMemRelease(pMem); |
- pMem->zMalloc = sqlite3DbMallocRaw(db, 64); |
+ pMem->zMalloc = sqlite3DbMallocRawNN(db, 64); |
if( db->mallocFailed ){ |
pMem->flags = MEM_Null; |
pMem->szMalloc = 0; |
@@ -760,7 +761,7 @@ int sqlite3VdbeMemTooBig(Mem *p){ |
void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ |
int i; |
Mem *pX; |
- for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){ |
+ for(i=0, pX=pVdbe->aMem; i<pVdbe->nMem; i++, pX++){ |
if( pX->pScopyFrom==pMem ){ |
pX->flags |= MEM_Undefined; |
pX->pScopyFrom = 0; |
@@ -801,10 +802,6 @@ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ |
int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ |
int rc = SQLITE_OK; |
- /* 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); |
@@ -904,7 +901,7 @@ int sqlite3VdbeMemSetStr( |
testcase( nAlloc==31 ); |
testcase( nAlloc==32 ); |
if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){ |
- return SQLITE_NOMEM; |
+ return SQLITE_NOMEM_BKPT; |
} |
memcpy(pMem->z, z, nAlloc); |
}else if( xDel==SQLITE_DYNAMIC ){ |
@@ -924,7 +921,7 @@ int sqlite3VdbeMemSetStr( |
#ifndef SQLITE_OMIT_UTF16 |
if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ |
- return SQLITE_NOMEM; |
+ return SQLITE_NOMEM_BKPT; |
} |
#endif |
@@ -937,10 +934,9 @@ int sqlite3VdbeMemSetStr( |
/* |
** Move data out of a btree key or data field and into a Mem structure. |
-** The data or key is taken from the entry that pCur is currently pointing |
+** The data is payload from the entry that pCur is currently pointing |
** to. offset and amt determine what portion of the data or key to retrieve. |
-** key is true to get the key or false to get data. The result is written |
-** into the pMem element. |
+** The result is written into the pMem element. |
** |
** The pMem object must have been initialized. This routine will use |
** pMem->zMalloc to hold the content from the btree, if possible. New |
@@ -955,17 +951,12 @@ 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); |
- } |
+ rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z); |
if( rc==SQLITE_OK ){ |
pMem->z[amt] = 0; |
pMem->z[amt+1] = 0; |
@@ -981,7 +972,6 @@ int sqlite3VdbeMemFromBtree( |
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. */ |
){ |
char *zData; /* Data from the btree layer */ |
@@ -994,11 +984,7 @@ int sqlite3VdbeMemFromBtree( |
/* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() |
** that both the BtShared and database handle mutexes are held. */ |
assert( (pMem->flags & MEM_RowSet)==0 ); |
- if( key ){ |
- zData = (char *)sqlite3BtreeKeyFetch(pCur, &available); |
- }else{ |
- zData = (char *)sqlite3BtreeDataFetch(pCur, &available); |
- } |
+ zData = (char *)sqlite3BtreePayloadFetch(pCur, &available); |
assert( zData!=0 ); |
if( offset+amt<=available ){ |
@@ -1006,7 +992,7 @@ int sqlite3VdbeMemFromBtree( |
pMem->flags = MEM_Blob|MEM_Ephem; |
pMem->n = (int)amt; |
}else{ |
- rc = vdbeMemFromBtreeResize(pCur, offset, amt, key, pMem); |
+ rc = vdbeMemFromBtreeResize(pCur, offset, amt, pMem); |
} |
return rc; |
@@ -1024,10 +1010,8 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ |
assert( (pVal->flags & MEM_RowSet)==0 ); |
assert( (pVal->flags & (MEM_Null))==0 ); |
if( pVal->flags & (MEM_Blob|MEM_Str) ){ |
+ if( ExpandBlob(pVal) ) return 0; |
pVal->flags |= MEM_Str; |
- if( pVal->flags & MEM_Zero ){ |
- sqlite3VdbeMemExpandBlob(pVal); |
- } |
if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){ |
sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); |
} |
@@ -1185,7 +1169,6 @@ static int valueFromFunction( |
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 */ |
@@ -1193,8 +1176,7 @@ static int valueFromFunction( |
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); |
+ pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0); |
assert( pFunc ); |
if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 |
|| (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) |
@@ -1205,7 +1187,7 @@ static int valueFromFunction( |
if( pList ){ |
apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal); |
if( apVal==0 ){ |
- rc = SQLITE_NOMEM; |
+ rc = SQLITE_NOMEM_BKPT; |
goto value_from_function_out; |
} |
for(i=0; i<nVal; i++){ |
@@ -1216,7 +1198,7 @@ static int valueFromFunction( |
pVal = valueNew(db, pCtx); |
if( pVal==0 ){ |
- rc = SQLITE_NOMEM; |
+ rc = SQLITE_NOMEM_BKPT; |
goto value_from_function_out; |
} |
@@ -1224,7 +1206,7 @@ static int valueFromFunction( |
memset(&ctx, 0, sizeof(ctx)); |
ctx.pOut = pVal; |
ctx.pFunc = pFunc; |
- pFunc->xFunc(&ctx, nVal, apVal); |
+ pFunc->xSFunc(&ctx, nVal, apVal); |
if( ctx.isError ){ |
rc = ctx.isError; |
sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); |
@@ -1282,11 +1264,8 @@ static int valueFromExpr( |
const char *zNeg = ""; |
int rc = SQLITE_OK; |
- if( !pExpr ){ |
- *ppVal = 0; |
- return SQLITE_OK; |
- } |
- while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft; |
+ assert( pExpr!=0 ); |
+ while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft; |
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; |
/* Compressed expressions only appear when parsing the DEFAULT clause |
@@ -1355,6 +1334,7 @@ static int valueFromExpr( |
}else if( op==TK_NULL ){ |
pVal = valueNew(db, pCtx); |
if( pVal==0 ) goto no_mem; |
+ sqlite3VdbeMemNumerify(pVal); |
} |
#ifndef SQLITE_OMIT_BLOB_LITERAL |
else if( op==TK_BLOB ){ |
@@ -1381,7 +1361,7 @@ static int valueFromExpr( |
return rc; |
no_mem: |
- db->mallocFailed = 1; |
+ sqlite3OomFault(db); |
sqlite3DbFree(db, zVal); |
assert( *ppVal==0 ); |
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
@@ -1389,7 +1369,7 @@ no_mem: |
#else |
assert( pCtx==0 ); sqlite3ValueFree(pVal); |
#endif |
- return SQLITE_NOMEM; |
+ return SQLITE_NOMEM_BKPT; |
} |
/* |
@@ -1409,7 +1389,7 @@ int sqlite3ValueFromExpr( |
u8 affinity, /* Affinity to use */ |
sqlite3_value **ppVal /* Write the new value here */ |
){ |
- return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0); |
+ return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0; |
} |
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
@@ -1440,7 +1420,7 @@ static void recordFunc( |
db = sqlite3_context_db_handle(context); |
nRet = 1 + nSerial + nVal; |
- aRet = sqlite3DbMallocRaw(db, nRet); |
+ aRet = sqlite3DbMallocRawNN(db, nRet); |
if( aRet==0 ){ |
sqlite3_result_error_nomem(context); |
}else{ |
@@ -1456,15 +1436,10 @@ static void recordFunc( |
** Register built-in functions used to help read ANALYZE data. |
*/ |
void sqlite3AnalyzeFunctions(void){ |
- static SQLITE_WSD FuncDef aAnalyzeTableFuncs[] = { |
+ static FuncDef aAnalyzeTableFuncs[] = { |
FUNCTION(sqlite_record, 1, 0, 0, recordFunc), |
}; |
- int i; |
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); |
- FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs); |
- for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){ |
- sqlite3FuncDefInsert(pHash, &aFunc[i]); |
- } |
+ sqlite3InsertBuiltinFuncs(aAnalyzeTableFuncs, ArraySize(aAnalyzeTableFuncs)); |
} |
/* |
@@ -1534,9 +1509,9 @@ static int stat4ValueFromExpr( |
** structures intended to be compared against sample index keys stored |
** in the sqlite_stat4 table. |
** |
-** A single call to this function attempts to populates field iVal (leftmost |
-** is 0 etc.) of the unpacked record with a value extracted from expression |
-** pExpr. Extraction of values is possible if: |
+** A single call to this function populates zero or more fields of the |
+** record starting with field iVal (fields are numbered from left to |
+** right starting with 0). A single field is populated if: |
** |
** * (pExpr==0). In this case the value is assumed to be an SQL NULL, |
** |
@@ -1545,10 +1520,14 @@ static int stat4ValueFromExpr( |
** * The sqlite3ValueFromExpr() function is able to extract a value |
** from the expression (i.e. the expression is a literal value). |
** |
-** If a value can be extracted, the affinity passed as the 5th argument |
-** is applied to it before it is copied into the UnpackedRecord. Output |
-** parameter *pbOk is set to true if a value is extracted, or false |
-** otherwise. |
+** Or, if pExpr is a TK_VECTOR, one field is populated for each of the |
+** vector components that match either of the two latter criteria listed |
+** above. |
+** |
+** Before any value is appended to the record, the affinity of the |
+** corresponding column within index pIdx is applied to it. Before |
+** this function returns, output parameter *pnExtract is set to the |
+** number of values appended to the record. |
** |
** When this function is called, *ppRec must either point to an object |
** allocated by an earlier call to this function, or must be NULL. If it |
@@ -1564,22 +1543,33 @@ int sqlite3Stat4ProbeSetValue( |
Index *pIdx, /* Index being probed */ |
UnpackedRecord **ppRec, /* IN/OUT: Probe record */ |
Expr *pExpr, /* The expression to extract a value from */ |
- u8 affinity, /* Affinity to use */ |
+ int nElem, /* Maximum number of values to append */ |
int iVal, /* Array element to populate */ |
- int *pbOk /* OUT: True if value was extracted */ |
+ int *pnExtract /* OUT: Values appended to the record */ |
){ |
- int rc; |
- sqlite3_value *pVal = 0; |
- struct ValueNewStat4Ctx alloc; |
+ int rc = SQLITE_OK; |
+ int nExtract = 0; |
- alloc.pParse = pParse; |
- alloc.pIdx = pIdx; |
- alloc.ppRec = ppRec; |
- alloc.iVal = iVal; |
+ if( pExpr==0 || pExpr->op!=TK_SELECT ){ |
+ int i; |
+ struct ValueNewStat4Ctx alloc; |
+ |
+ alloc.pParse = pParse; |
+ alloc.pIdx = pIdx; |
+ alloc.ppRec = ppRec; |
+ |
+ for(i=0; i<nElem; i++){ |
+ sqlite3_value *pVal = 0; |
+ Expr *pElem = (pExpr ? sqlite3VectorFieldSubexpr(pExpr, i) : 0); |
+ u8 aff = sqlite3IndexColumnAffinity(pParse->db, pIdx, iVal+i); |
+ alloc.iVal = iVal+i; |
+ rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc, &pVal); |
+ if( !pVal ) break; |
+ nExtract++; |
+ } |
+ } |
- rc = stat4ValueFromExpr(pParse, pExpr, affinity, &alloc, &pVal); |
- assert( pVal==0 || pVal->db==pParse->db ); |
- *pbOk = (pVal!=0); |
+ *pnExtract = nExtract; |
return rc; |
} |
@@ -1643,7 +1633,7 @@ int sqlite3Stat4Column( |
if( iField>nRec ) return SQLITE_CORRUPT_BKPT; |
if( pMem==0 ){ |
pMem = *ppVal = sqlite3ValueNew(db); |
- if( pMem==0 ) return SQLITE_NOMEM; |
+ if( pMem==0 ) return SQLITE_NOMEM_BKPT; |
} |
sqlite3VdbeSerialGet(&a[iField-szField], t, pMem); |
pMem->enc = ENC(db); |