|
|
@@ -1158,7 +1158,7 @@ extern "C" {
|
|
|
*/
|
|
|
#define SQLITE_VERSION "3.25.0"
|
|
|
#define SQLITE_VERSION_NUMBER 3025000
|
|
|
-#define SQLITE_SOURCE_ID "2018-09-06 20:33:11 10c3e5a0314470ee1ffc37b68445a2cb2054530346d5f5ed3ffbd6df8003alt1"
|
|
|
+#define SQLITE_SOURCE_ID "2018-09-08 20:29:04 5a954533edbde58aa7158572ece7ceeb1c6e610b71f3ae45d0b8371d74f9alt1"
|
|
|
|
|
|
/*
|
|
|
** CAPI3REF: Run-Time Library Version Numbers
|
|
|
@@ -18679,7 +18679,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
|
|
|
SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
|
|
|
SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
|
|
|
SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
|
|
|
-SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo*);
|
|
|
+SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*);
|
|
|
SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*);
|
|
|
SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*);
|
|
|
SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*);
|
|
|
@@ -88567,6 +88567,7 @@ case OP_ParseSchema: {
|
|
|
initData.db = db;
|
|
|
initData.iDb = pOp->p1;
|
|
|
initData.pzErrMsg = &p->zErrMsg;
|
|
|
+ initData.mInitFlags = 0;
|
|
|
zSql = sqlite3MPrintf(db,
|
|
|
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
|
|
|
db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
|
|
|
@@ -102311,29 +102312,30 @@ static int renameEditSql(
|
|
|
*/
|
|
|
static int renameResolveTrigger(Parse *pParse, const char *zDb){
|
|
|
sqlite3 *db = pParse->db;
|
|
|
+ Trigger *pNew = pParse->pNewTrigger;
|
|
|
TriggerStep *pStep;
|
|
|
NameContext sNC;
|
|
|
int rc = SQLITE_OK;
|
|
|
|
|
|
memset(&sNC, 0, sizeof(sNC));
|
|
|
sNC.pParse = pParse;
|
|
|
- pParse->pTriggerTab = sqlite3FindTable(db, pParse->pNewTrigger->table, zDb);
|
|
|
- pParse->eTriggerOp = pParse->pNewTrigger->op;
|
|
|
+ assert( pNew->pTabSchema );
|
|
|
+ pParse->pTriggerTab = sqlite3FindTable(db, pNew->table,
|
|
|
+ db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName
|
|
|
+ );
|
|
|
+ pParse->eTriggerOp = pNew->op;
|
|
|
|
|
|
/* Resolve symbols in WHEN clause */
|
|
|
- if( pParse->pNewTrigger->pWhen ){
|
|
|
- rc = sqlite3ResolveExprNames(&sNC, pParse->pNewTrigger->pWhen);
|
|
|
+ if( pNew->pWhen ){
|
|
|
+ rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen);
|
|
|
}
|
|
|
|
|
|
- for(pStep=pParse->pNewTrigger->step_list;
|
|
|
- rc==SQLITE_OK && pStep;
|
|
|
- pStep=pStep->pNext
|
|
|
- ){
|
|
|
+ for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){
|
|
|
if( pStep->pSelect ){
|
|
|
sqlite3SelectPrep(pParse, pStep->pSelect, &sNC);
|
|
|
if( pParse->nErr ) rc = pParse->rc;
|
|
|
}
|
|
|
- if( rc==SQLITE_OK && pStep->zTarget ){
|
|
|
+ if( rc==SQLITE_OK && pStep->zTarget ){
|
|
|
Table *pTarget = sqlite3LocateTable(pParse, 0, pStep->zTarget, zDb);
|
|
|
if( pTarget==0 ){
|
|
|
rc = SQLITE_ERROR;
|
|
|
@@ -102697,10 +102699,12 @@ static void renameTableFunc(
|
|
|
}else{
|
|
|
/* Modify any FK definitions to point to the new table. */
|
|
|
#ifndef SQLITE_OMIT_FOREIGN_KEY
|
|
|
- FKey *pFKey;
|
|
|
- for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
|
|
|
- if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
|
|
|
- renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo);
|
|
|
+ if( db->flags & SQLITE_ForeignKeys ){
|
|
|
+ FKey *pFKey;
|
|
|
+ for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
|
|
|
+ if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
|
|
|
+ renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
#endif
|
|
|
@@ -109666,8 +109670,10 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
|
|
|
}
|
|
|
assert( p->nSrc>0 );
|
|
|
pItem = &p->a[p->nSrc-1];
|
|
|
+ assert( (pTable==0)==(pDatabase==0) );
|
|
|
+ assert( pItem->zName==0 || pDatabase!=0 );
|
|
|
if( IN_RENAME_OBJECT && pItem->zName ){
|
|
|
- Token *pToken = (pDatabase && pDatabase->z) ? pDatabase : pTable;
|
|
|
+ Token *pToken = (ALWAYS(pDatabase) && pDatabase->z) ? pDatabase : pTable;
|
|
|
sqlite3RenameTokenMap(pParse, pItem->zName, pToken);
|
|
|
}
|
|
|
assert( pAlias!=0 );
|
|
|
@@ -123366,8 +123372,8 @@ struct SortCtx {
|
|
|
int labelBkOut; /* Start label for the block-output subroutine */
|
|
|
int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */
|
|
|
int labelDone; /* Jump here when done, ex: LIMIT reached */
|
|
|
+ int labelOBLopt; /* Jump here when sorter is full */
|
|
|
u8 sortFlags; /* Zero or more SORTFLAG_* bits */
|
|
|
- u8 bOrderedInnerLoop; /* ORDER BY correctly sorts the inner loop */
|
|
|
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
|
|
|
u8 nDefer; /* Number of valid entries in aDefer[] */
|
|
|
struct DeferredCsr {
|
|
|
@@ -123991,10 +123997,10 @@ static void pushOntoSorter(
|
|
|
** than LIMIT+OFFSET items in the sorter.
|
|
|
**
|
|
|
** If the new record does not need to be inserted into the sorter,
|
|
|
- ** jump to the next iteration of the loop. Or, if the
|
|
|
- ** pSort->bOrderedInnerLoop flag is set to indicate that the inner
|
|
|
- ** loop delivers items in sorted order, jump to the next iteration
|
|
|
- ** of the outer loop.
|
|
|
+ ** jump to the next iteration of the loop. If the pSort->labelOBLopt
|
|
|
+ ** value is not zero, then it is a label of where to jump. Otherwise,
|
|
|
+ ** just bypass the row insert logic. See the header comment on the
|
|
|
+ ** sqlite3WhereOrderByLimitOptLabel() function for additional info.
|
|
|
*/
|
|
|
int iCsr = pSort->iECursor;
|
|
|
sqlite3VdbeAddOp2(v, OP_IfNotZero, iLimit, sqlite3VdbeCurrentAddr(v)+4);
|
|
|
@@ -124016,9 +124022,8 @@ static void pushOntoSorter(
|
|
|
sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord,
|
|
|
regBase+nOBSat, nBase-nOBSat);
|
|
|
if( iSkip ){
|
|
|
- assert( pSort->bOrderedInnerLoop==0 || pSort->bOrderedInnerLoop==1 );
|
|
|
sqlite3VdbeChangeP2(v, iSkip,
|
|
|
- sqlite3VdbeCurrentAddr(v) + pSort->bOrderedInnerLoop);
|
|
|
+ pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -129358,7 +129363,7 @@ SQLITE_PRIVATE int sqlite3Select(
|
|
|
}
|
|
|
if( sSort.pOrderBy ){
|
|
|
sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo);
|
|
|
- sSort.bOrderedInnerLoop = sqlite3WhereOrderedInnerLoop(pWInfo);
|
|
|
+ sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo);
|
|
|
if( sSort.nOBSat==sSort.pOrderBy->nExpr ){
|
|
|
sSort.pOrderBy = 0;
|
|
|
}
|
|
|
@@ -138570,15 +138575,38 @@ SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
-** Return TRUE if the innermost loop of the WHERE clause implementation
|
|
|
-** returns rows in ORDER BY order for complete run of the inner loop.
|
|
|
+** In the ORDER BY LIMIT optimization, if the inner-most loop is known
|
|
|
+** to emit rows in increasing order, and if the last row emitted by the
|
|
|
+** inner-most loop did not fit within the sorter, then we can skip all
|
|
|
+** subsequent rows for the current iteration of the inner loop (because they
|
|
|
+** will not fit in the sorter either) and continue with the second inner
|
|
|
+** loop - the loop immediately outside the inner-most.
|
|
|
**
|
|
|
-** Across multiple iterations of outer loops, the output rows need not be
|
|
|
-** sorted. As long as rows are sorted for just the innermost loop, this
|
|
|
-** routine can return TRUE.
|
|
|
+** When a row does not fit in the sorter (because the sorter already
|
|
|
+** holds LIMIT+OFFSET rows that are smaller), then a jump is made to the
|
|
|
+** label returned by this function.
|
|
|
+**
|
|
|
+** If the ORDER BY LIMIT optimization applies, the jump destination should
|
|
|
+** be the continuation for the second-inner-most loop. If the ORDER BY
|
|
|
+** LIMIT optimization does not apply, then the jump destination should
|
|
|
+** be the continuation for the inner-most loop.
|
|
|
+**
|
|
|
+** It is always safe for this routine to return the continuation of the
|
|
|
+** inner-most loop, in the sense that a correct answer will result.
|
|
|
+** Returning the continuation the second inner loop is an optimization
|
|
|
+** that might make the code run a little faster, but should not change
|
|
|
+** the final answer.
|
|
|
*/
|
|
|
-SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo *pWInfo){
|
|
|
- return pWInfo->bOrderedInnerLoop;
|
|
|
+SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){
|
|
|
+ WhereLevel *pInner;
|
|
|
+ if( !pWInfo->bOrderedInnerLoop ){
|
|
|
+ /* The ORDER BY LIMIT optimization does not apply. Jump to the
|
|
|
+ ** continuation of the inner-most loop. */
|
|
|
+ return pWInfo->iContinue;
|
|
|
+ }
|
|
|
+ pInner = &pWInfo->a[pWInfo->nLevel-1];
|
|
|
+ assert( pInner->addrNxt!=0 );
|
|
|
+ return pInner->addrNxt;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -142751,6 +142779,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
|
|
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
|
|
|
}
|
|
|
}
|
|
|
+ pWInfo->bOrderedInnerLoop = 0;
|
|
|
if( pWInfo->pOrderBy ){
|
|
|
if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
|
|
|
if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
|
|
|
@@ -216116,7 +216145,7 @@ static void fts5SourceIdFunc(
|
|
|
){
|
|
|
assert( nArg==0 );
|
|
|
UNUSED_PARAM2(nArg, apUnused);
|
|
|
- sqlite3_result_text(pCtx, "fts5: 2018-09-06 20:33:11 10c3e5a0314470ee1ffc37b68445a2cb2054530346d5f5ed3ffbd6df8003cad0", -1, SQLITE_TRANSIENT);
|
|
|
+ sqlite3_result_text(pCtx, "fts5: 2018-09-08 20:29:04 5a954533edbde58aa7158572ece7ceeb1c6e610b71f3ae45d0b8371d74f9fea5", -1, SQLITE_TRANSIENT);
|
|
|
}
|
|
|
|
|
|
static int fts5Init(sqlite3 *db){
|
|
|
@@ -230501,9 +230530,9 @@ static void print_elem(void *e, sqlite_int64 c, void* p){
|
|
|
#endif
|
|
|
|
|
|
/************** End of extension-functions.c *********************************/
|
|
|
-#if __LINE__!=230504
|
|
|
+#if __LINE__!=230533
|
|
|
#undef SQLITE_SOURCE_ID
|
|
|
-#define SQLITE_SOURCE_ID "2018-09-06 20:33:11 10c3e5a0314470ee1ffc37b68445a2cb2054530346d5f5ed3ffbd6df8003alt2"
|
|
|
+#define SQLITE_SOURCE_ID "2018-09-08 20:29:04 5a954533edbde58aa7158572ece7ceeb1c6e610b71f3ae45d0b8371d74f9alt2"
|
|
|
#endif
|
|
|
/* Return the source-id for this library */
|
|
|
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
|