|
|
|
@ -1,6 +1,6 @@
|
|
|
|
|
/******************************************************************************
|
|
|
|
|
** This file is an amalgamation of many separate C source files from SQLite
|
|
|
|
|
** version 3.41.0. By combining all the individual C code files into this
|
|
|
|
|
** version 3.41.2. By combining all the individual C code files into this
|
|
|
|
|
** single large file, the entire code can be compiled as a single translation
|
|
|
|
|
** unit. This allows many compilers to do optimizations that would not be
|
|
|
|
|
** possible if the files were compiled separately. Performance improvements
|
|
|
|
@ -452,9 +452,9 @@ extern "C" {
|
|
|
|
|
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
|
|
|
|
** [sqlite_version()] and [sqlite_source_id()].
|
|
|
|
|
*/
|
|
|
|
|
#define SQLITE_VERSION "3.41.0"
|
|
|
|
|
#define SQLITE_VERSION_NUMBER 3041000
|
|
|
|
|
#define SQLITE_SOURCE_ID "2023-02-21 18:09:37 05941c2a04037fc3ed2ffae11f5d2260706f89431f463518740f72ada350866d"
|
|
|
|
|
#define SQLITE_VERSION "3.41.2"
|
|
|
|
|
#define SQLITE_VERSION_NUMBER 3041002
|
|
|
|
|
#define SQLITE_SOURCE_ID "2023-03-22 11:56:21 0d1fc92f94cb6b76bffe3ec34d69cffde2924203304e8ffc4155597af0c191da"
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** CAPI3REF: Run-Time Library Version Numbers
|
|
|
|
@ -16592,7 +16592,7 @@ struct PgHdr {
|
|
|
|
|
** private to pcache.c and should not be accessed by other modules.
|
|
|
|
|
** pCache is grouped with the public elements for efficiency.
|
|
|
|
|
*/
|
|
|
|
|
i16 nRef; /* Number of users of this page */
|
|
|
|
|
i64 nRef; /* Number of users of this page */
|
|
|
|
|
PgHdr *pDirtyNext; /* Next element in list of dirty pages */
|
|
|
|
|
PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */
|
|
|
|
|
/* NB: pDirtyNext and pDirtyPrev are undefined if the
|
|
|
|
@ -16673,12 +16673,12 @@ SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *);
|
|
|
|
|
SQLITE_PRIVATE void sqlite3PcacheClear(PCache*);
|
|
|
|
|
|
|
|
|
|
/* Return the total number of outstanding page references */
|
|
|
|
|
SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache*);
|
|
|
|
|
SQLITE_PRIVATE i64 sqlite3PcacheRefCount(PCache*);
|
|
|
|
|
|
|
|
|
|
/* Increment the reference count of an existing page */
|
|
|
|
|
SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr*);
|
|
|
|
|
|
|
|
|
|
SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr*);
|
|
|
|
|
SQLITE_PRIVATE i64 sqlite3PcachePageRefcount(PgHdr*);
|
|
|
|
|
|
|
|
|
|
/* Return the total number of pages stored in the cache */
|
|
|
|
|
SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*);
|
|
|
|
@ -18837,7 +18837,7 @@ struct NameContext {
|
|
|
|
|
#define NC_HasAgg 0x000010 /* One or more aggregate functions seen */
|
|
|
|
|
#define NC_IdxExpr 0x000020 /* True if resolving columns of CREATE INDEX */
|
|
|
|
|
#define NC_SelfRef 0x00002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */
|
|
|
|
|
#define NC_VarSelect 0x000040 /* A correlated subquery has been seen */
|
|
|
|
|
#define NC_Subquery 0x000040 /* A subquery has been seen */
|
|
|
|
|
#define NC_UEList 0x000080 /* True if uNC.pEList is used */
|
|
|
|
|
#define NC_UAggInfo 0x000100 /* True if uNC.pAggInfo is used */
|
|
|
|
|
#define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */
|
|
|
|
@ -19156,6 +19156,7 @@ struct IndexedExpr {
|
|
|
|
|
int iIdxCur; /* The index cursor */
|
|
|
|
|
int iIdxCol; /* The index column that contains value of pExpr */
|
|
|
|
|
u8 bMaybeNullRow; /* True if we need an OP_IfNullRow check */
|
|
|
|
|
u8 aff; /* Affinity of the pExpr expression */
|
|
|
|
|
IndexedExpr *pIENext; /* Next in a list of all indexed expressions */
|
|
|
|
|
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
|
|
|
|
|
const char *zIdxName; /* Name of index, used only for bytecode comments */
|
|
|
|
@ -19207,6 +19208,9 @@ struct Parse {
|
|
|
|
|
u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */
|
|
|
|
|
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
|
|
|
|
|
u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef SQLITE_DEBUG
|
|
|
|
|
u8 ifNotExists; /* Might be true if IF NOT EXISTS. Assert()s only */
|
|
|
|
|
#endif
|
|
|
|
|
int nRangeReg; /* Size of the temporary register block */
|
|
|
|
|
int iRangeReg; /* First register in temporary register block */
|
|
|
|
@ -52653,7 +52657,7 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
|
|
|
|
|
struct PCache {
|
|
|
|
|
PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */
|
|
|
|
|
PgHdr *pSynced; /* Last synced page in dirty page list */
|
|
|
|
|
int nRefSum; /* Sum of ref counts over all pages */
|
|
|
|
|
i64 nRefSum; /* Sum of ref counts over all pages */
|
|
|
|
|
int szCache; /* Configured cache size */
|
|
|
|
|
int szSpill; /* Size before spilling occurs */
|
|
|
|
|
int szPage; /* Size of every page in this cache */
|
|
|
|
@ -52683,7 +52687,7 @@ struct PCache {
|
|
|
|
|
unsigned char *a;
|
|
|
|
|
int j;
|
|
|
|
|
pPg = (PgHdr*)pLower->pExtra;
|
|
|
|
|
printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags);
|
|
|
|
|
printf("%3lld: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags);
|
|
|
|
|
a = (unsigned char *)pLower->pBuf;
|
|
|
|
|
for(j=0; j<12; j++) printf("%02x", a[j]);
|
|
|
|
|
printf(" ptr %p\n", pPg);
|
|
|
|
@ -53427,14 +53431,14 @@ SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){
|
|
|
|
|
** This is not the total number of pages referenced, but the sum of the
|
|
|
|
|
** reference count for all pages.
|
|
|
|
|
*/
|
|
|
|
|
SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){
|
|
|
|
|
SQLITE_PRIVATE i64 sqlite3PcacheRefCount(PCache *pCache){
|
|
|
|
|
return pCache->nRefSum;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Return the number of references to the page supplied as an argument.
|
|
|
|
|
*/
|
|
|
|
|
SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){
|
|
|
|
|
SQLITE_PRIVATE i64 sqlite3PcachePageRefcount(PgHdr *p){
|
|
|
|
|
return p->nRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -74504,7 +74508,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
|
|
|
|
|
|
|
|
|
|
pPage = pCur->pPage;
|
|
|
|
|
idx = ++pCur->ix;
|
|
|
|
|
if( NEVER(!pPage->isInit) || sqlite3FaultSim(412) ){
|
|
|
|
|
if( !pPage->isInit || sqlite3FaultSim(412) ){
|
|
|
|
|
return SQLITE_CORRUPT_BKPT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -77633,6 +77637,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
|
|
|
|
|
assert( szNew==pPage->xCellSize(pPage, newCell) );
|
|
|
|
|
assert( szNew <= MX_CELL_SIZE(p->pBt) );
|
|
|
|
|
idx = pCur->ix;
|
|
|
|
|
pCur->info.nSize = 0;
|
|
|
|
|
if( loc==0 ){
|
|
|
|
|
CellInfo info;
|
|
|
|
|
assert( idx>=0 );
|
|
|
|
@ -77705,7 +77710,6 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
|
|
|
|
|
** larger than the largest existing key, it is possible to insert the
|
|
|
|
|
** row without seeking the cursor. This can be a big performance boost.
|
|
|
|
|
*/
|
|
|
|
|
pCur->info.nSize = 0;
|
|
|
|
|
if( pPage->nOverflow ){
|
|
|
|
|
assert( rc==SQLITE_OK );
|
|
|
|
|
pCur->curFlags &= ~(BTCF_ValidNKey);
|
|
|
|
@ -90915,8 +90919,7 @@ static u64 filterHash(const Mem *aMem, const Op *pOp){
|
|
|
|
|
}else if( p->flags & MEM_Real ){
|
|
|
|
|
h += sqlite3VdbeIntValue(p);
|
|
|
|
|
}else if( p->flags & (MEM_Str|MEM_Blob) ){
|
|
|
|
|
h += p->n;
|
|
|
|
|
if( p->flags & MEM_Zero ) h += p->u.nZero;
|
|
|
|
|
/* no-op */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return h;
|
|
|
|
@ -104495,14 +104498,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
|
|
|
|
if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){
|
|
|
|
|
testcase( ExprHasProperty(pExpr, EP_OuterON) );
|
|
|
|
|
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
|
|
|
|
if( pExpr->op==TK_NOTNULL ){
|
|
|
|
|
pExpr->u.zToken = "true";
|
|
|
|
|
ExprSetProperty(pExpr, EP_IsTrue);
|
|
|
|
|
}else{
|
|
|
|
|
pExpr->u.zToken = "false";
|
|
|
|
|
ExprSetProperty(pExpr, EP_IsFalse);
|
|
|
|
|
}
|
|
|
|
|
pExpr->op = TK_TRUEFALSE;
|
|
|
|
|
pExpr->u.iValue = (pExpr->op==TK_NOTNULL);
|
|
|
|
|
pExpr->flags |= EP_IntValue;
|
|
|
|
|
pExpr->op = TK_INTEGER;
|
|
|
|
|
|
|
|
|
|
for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){
|
|
|
|
|
p->nRef = anRef[i];
|
|
|
|
|
}
|
|
|
|
@ -104804,8 +104803,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
|
|
|
|
assert( pNC->nRef>=nRef );
|
|
|
|
|
if( nRef!=pNC->nRef ){
|
|
|
|
|
ExprSetProperty(pExpr, EP_VarSelect);
|
|
|
|
|
pNC->ncFlags |= NC_VarSelect;
|
|
|
|
|
}
|
|
|
|
|
pNC->ncFlags |= NC_Subquery;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@ -109554,6 +109553,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(
|
|
|
|
|
){
|
|
|
|
|
int iAddr;
|
|
|
|
|
Vdbe *v = pParse->pVdbe;
|
|
|
|
|
int nErr = pParse->nErr;
|
|
|
|
|
assert( v!=0 );
|
|
|
|
|
assert( pParse->iSelfTab!=0 );
|
|
|
|
|
if( pParse->iSelfTab>0 ){
|
|
|
|
@ -109566,6 +109566,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(
|
|
|
|
|
sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1);
|
|
|
|
|
}
|
|
|
|
|
if( iAddr ) sqlite3VdbeJumpHere(v, iAddr);
|
|
|
|
|
if( pParse->nErr>nErr ) pParse->db->errByteOffset = -1;
|
|
|
|
|
}
|
|
|
|
|
#endif /* SQLITE_OMIT_GENERATED_COLUMNS */
|
|
|
|
|
|
|
|
|
@ -109582,6 +109583,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(
|
|
|
|
|
Column *pCol;
|
|
|
|
|
assert( v!=0 );
|
|
|
|
|
assert( pTab!=0 );
|
|
|
|
|
assert( iCol!=XN_EXPR );
|
|
|
|
|
if( iCol<0 || iCol==pTab->iPKey ){
|
|
|
|
|
sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
|
|
|
|
|
VdbeComment((v, "%s.rowid", pTab->zName));
|
|
|
|
@ -109848,6 +109850,7 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup(
|
|
|
|
|
IndexedExpr *p;
|
|
|
|
|
Vdbe *v;
|
|
|
|
|
for(p=pParse->pIdxEpr; p; p=p->pIENext){
|
|
|
|
|
u8 exprAff;
|
|
|
|
|
int iDataCur = p->iDataCur;
|
|
|
|
|
if( iDataCur<0 ) continue;
|
|
|
|
|
if( pParse->iSelfTab ){
|
|
|
|
@ -109855,6 +109858,16 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup(
|
|
|
|
|
iDataCur = -1;
|
|
|
|
|
}
|
|
|
|
|
if( sqlite3ExprCompare(0, pExpr, p->pExpr, iDataCur)!=0 ) continue;
|
|
|
|
|
assert( p->aff>=SQLITE_AFF_BLOB && p->aff<=SQLITE_AFF_NUMERIC );
|
|
|
|
|
exprAff = sqlite3ExprAffinity(pExpr);
|
|
|
|
|
if( (exprAff<=SQLITE_AFF_BLOB && p->aff!=SQLITE_AFF_BLOB)
|
|
|
|
|
|| (exprAff==SQLITE_AFF_TEXT && p->aff!=SQLITE_AFF_TEXT)
|
|
|
|
|
|| (exprAff>=SQLITE_AFF_NUMERIC && p->aff!=SQLITE_AFF_NUMERIC)
|
|
|
|
|
){
|
|
|
|
|
/* Affinity mismatch on a generated column */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v = pParse->pVdbe;
|
|
|
|
|
assert( v!=0 );
|
|
|
|
|
if( p->bMaybeNullRow ){
|
|
|
|
@ -110434,10 +110447,13 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
|
|
|
|
|
return target;
|
|
|
|
|
}
|
|
|
|
|
case TK_COLLATE: {
|
|
|
|
|
if( !ExprHasProperty(pExpr, EP_Collate)
|
|
|
|
|
&& ALWAYS(pExpr->pLeft)
|
|
|
|
|
&& pExpr->pLeft->op==TK_FUNCTION
|
|
|
|
|
){
|
|
|
|
|
if( !ExprHasProperty(pExpr, EP_Collate) ){
|
|
|
|
|
/* A TK_COLLATE Expr node without the EP_Collate tag is a so-called
|
|
|
|
|
** "SOFT-COLLATE" that is added to constraints that are pushed down
|
|
|
|
|
** from outer queries into sub-queries by the push-down optimization.
|
|
|
|
|
** Clear subtypes as subtypes may not cross a subquery boundary.
|
|
|
|
|
*/
|
|
|
|
|
assert( pExpr->pLeft );
|
|
|
|
|
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
|
|
|
|
|
if( inReg!=target ){
|
|
|
|
|
sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target);
|
|
|
|
@ -110545,16 +110561,22 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
|
|
|
|
|
/* Temporarily disable factoring of constant expressions, since
|
|
|
|
|
** even though expressions may appear to be constant, they are not
|
|
|
|
|
** really constant because they originate from the right-hand side
|
|
|
|
|
** of a LEFT JOIN. */
|
|
|
|
|
pParse->okConstFactor = 0;
|
|
|
|
|
addrINR = sqlite3VdbeAddOp3(v, OP_IfNullRow, pExpr->iTable, 0, target);
|
|
|
|
|
/* The OP_IfNullRow opcode above can overwrite the result register with
|
|
|
|
|
** NULL. So we have to ensure that the result register is not a value
|
|
|
|
|
** that is suppose to be a constant. Two defenses are needed:
|
|
|
|
|
** (1) Temporarily disable factoring of constant expressions
|
|
|
|
|
** (2) Make sure the computed value really is stored in register
|
|
|
|
|
** "target" and not someplace else.
|
|
|
|
|
*/
|
|
|
|
|
pParse->okConstFactor = 0; /* note (1) above */
|
|
|
|
|
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
|
|
|
|
|
pParse->okConstFactor = okConstFactor;
|
|
|
|
|
if( inReg!=target ){ /* note (2) above */
|
|
|
|
|
sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target);
|
|
|
|
|
inReg = target;
|
|
|
|
|
}
|
|
|
|
|
sqlite3VdbeJumpHere(v, addrINR);
|
|
|
|
|
sqlite3VdbeChangeP3(v, addrINR, inReg);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -118917,7 +118939,7 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){
|
|
|
|
|
if( pParse->pNewTrigger ){
|
|
|
|
|
sqlite3ErrorMsg(pParse, "cannot use RETURNING in a trigger");
|
|
|
|
|
}else{
|
|
|
|
|
assert( pParse->bReturning==0 );
|
|
|
|
|
assert( pParse->bReturning==0 || pParse->ifNotExists );
|
|
|
|
|
}
|
|
|
|
|
pParse->bReturning = 1;
|
|
|
|
|
pRet = sqlite3DbMallocZero(db, sizeof(*pRet));
|
|
|
|
@ -118943,7 +118965,8 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){
|
|
|
|
|
pRet->retTStep.pTrig = &pRet->retTrig;
|
|
|
|
|
pRet->retTStep.pExprList = pList;
|
|
|
|
|
pHash = &(db->aDb[1].pSchema->trigHash);
|
|
|
|
|
assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 || pParse->nErr );
|
|
|
|
|
assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0
|
|
|
|
|
|| pParse->nErr || pParse->ifNotExists );
|
|
|
|
|
if( sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, &pRet->retTrig)
|
|
|
|
|
==&pRet->retTrig ){
|
|
|
|
|
sqlite3OomFault(db);
|
|
|
|
@ -119478,6 +119501,7 @@ SQLITE_PRIVATE void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType
|
|
|
|
|
** turn it into one by adding a unary "+" operator. */
|
|
|
|
|
pExpr = sqlite3PExpr(pParse, TK_UPLUS, pExpr, 0);
|
|
|
|
|
}
|
|
|
|
|
if( pExpr && pExpr->op!=TK_RAISE ) pExpr->affExpr = pCol->affinity;
|
|
|
|
|
sqlite3ColumnSetExpr(pParse, pTab, pCol, pExpr);
|
|
|
|
|
pExpr = 0;
|
|
|
|
|
goto generated_done;
|
|
|
|
@ -124184,7 +124208,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
|
|
|
|
|
#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
|
|
|
|
|
{
|
|
|
|
|
u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK;
|
|
|
|
|
if( sNC.ncFlags & NC_VarSelect ) bComplex = 1;
|
|
|
|
|
if( sNC.ncFlags & NC_Subquery ) bComplex = 1;
|
|
|
|
|
wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW);
|
|
|
|
|
if( HasRowid(pTab) ){
|
|
|
|
|
/* For a rowid table, initialize the RowSet to an empty set */
|
|
|
|
@ -126881,6 +126905,18 @@ static void ceilingFunc(
|
|
|
|
|
static double xCeil(double x){ return ceil(x); }
|
|
|
|
|
static double xFloor(double x){ return floor(x); }
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Some systems do not have log2() and log10() in their standard math
|
|
|
|
|
** libraries.
|
|
|
|
|
*/
|
|
|
|
|
#if defined(HAVE_LOG10) && HAVE_LOG10==0
|
|
|
|
|
# define log10(X) (0.4342944819032517867*log(X))
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(HAVE_LOG2) && HAVE_LOG2==0
|
|
|
|
|
# define log2(X) (1.442695040888963456*log(X))
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Implementation of SQL functions:
|
|
|
|
|
**
|
|
|
|
@ -136260,6 +136296,23 @@ SQLITE_PRIVATE void sqlite3Pragma(
|
|
|
|
|
jmp4 = integrityCheckResultRow(v);
|
|
|
|
|
sqlite3VdbeJumpHere(v, jmp2);
|
|
|
|
|
|
|
|
|
|
/* The OP_IdxRowid opcode is an optimized version of OP_Column
|
|
|
|
|
** that extracts the rowid off the end of the index record.
|
|
|
|
|
** But it only works correctly if index record does not have
|
|
|
|
|
** any extra bytes at the end. Verify that this is the case. */
|
|
|
|
|
if( HasRowid(pTab) ){
|
|
|
|
|
int jmp7;
|
|
|
|
|
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur+j, 3);
|
|
|
|
|
jmp7 = sqlite3VdbeAddOp3(v, OP_Eq, 3, 0, r1+pIdx->nColumn-1);
|
|
|
|
|
VdbeCoverage(v);
|
|
|
|
|
sqlite3VdbeLoadString(v, 3,
|
|
|
|
|
"rowid not at end-of-record for row ");
|
|
|
|
|
sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
|
|
|
|
|
sqlite3VdbeLoadString(v, 4, " of index ");
|
|
|
|
|
sqlite3VdbeGoto(v, jmp5-1);
|
|
|
|
|
sqlite3VdbeJumpHere(v, jmp7);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Any indexed columns with non-BINARY collations must still hold
|
|
|
|
|
** the exact same text value as the table. */
|
|
|
|
|
label6 = 0;
|
|
|
|
@ -140555,8 +140608,6 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(
|
|
|
|
|
pCol->affinity = sqlite3ExprAffinity(p);
|
|
|
|
|
if( pCol->affinity<=SQLITE_AFF_NONE ){
|
|
|
|
|
pCol->affinity = aff;
|
|
|
|
|
}else if( pCol->affinity>=SQLITE_AFF_NUMERIC && p->op==TK_CAST ){
|
|
|
|
|
pCol->affinity = SQLITE_AFF_FLEXNUM;
|
|
|
|
|
}
|
|
|
|
|
if( pCol->affinity>=SQLITE_AFF_TEXT && pSelect->pNext ){
|
|
|
|
|
int m = 0;
|
|
|
|
@ -140570,6 +140621,9 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(
|
|
|
|
|
if( pCol->affinity>=SQLITE_AFF_NUMERIC && (m&0x02)!=0 ){
|
|
|
|
|
pCol->affinity = SQLITE_AFF_BLOB;
|
|
|
|
|
}
|
|
|
|
|
if( pCol->affinity>=SQLITE_AFF_NUMERIC && p->op==TK_CAST ){
|
|
|
|
|
pCol->affinity = SQLITE_AFF_FLEXNUM;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
zType = columnType(&sNC, p, 0, 0, 0);
|
|
|
|
|
if( zType==0 || pCol->affinity!=sqlite3AffinityType(zType, 0) ){
|
|
|
|
@ -142084,7 +142138,9 @@ static Expr *substExpr(
|
|
|
|
|
sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
|
|
|
|
|
}else{
|
|
|
|
|
sqlite3 *db = pSubst->pParse->db;
|
|
|
|
|
if( pSubst->isOuterJoin && pCopy->op!=TK_COLUMN ){
|
|
|
|
|
if( pSubst->isOuterJoin
|
|
|
|
|
&& (pCopy->op!=TK_COLUMN || pCopy->iTable!=pSubst->iNewTable)
|
|
|
|
|
){
|
|
|
|
|
memset(&ifNullRow, 0, sizeof(ifNullRow));
|
|
|
|
|
ifNullRow.op = TK_IF_NULL_ROW;
|
|
|
|
|
ifNullRow.pLeft = pCopy;
|
|
|
|
@ -144600,10 +144656,12 @@ static void optimizeAggregateUseOfIndexedExpr(
|
|
|
|
|
NameContext *pNC /* Name context used to resolve agg-func args */
|
|
|
|
|
){
|
|
|
|
|
assert( pAggInfo->iFirstReg==0 );
|
|
|
|
|
assert( pSelect!=0 );
|
|
|
|
|
assert( pSelect->pGroupBy!=0 );
|
|
|
|
|
pAggInfo->nColumn = pAggInfo->nAccumulator;
|
|
|
|
|
if( ALWAYS(pAggInfo->nSortingColumn>0) ){
|
|
|
|
|
if( pAggInfo->nColumn==0 ){
|
|
|
|
|
pAggInfo->nSortingColumn = 0;
|
|
|
|
|
pAggInfo->nSortingColumn = pSelect->pGroupBy->nExpr;
|
|
|
|
|
}else{
|
|
|
|
|
pAggInfo->nSortingColumn =
|
|
|
|
|
pAggInfo->aCol[pAggInfo->nColumn-1].iSorterColumn+1;
|
|
|
|
@ -145028,6 +145086,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
|
|
|
|
|
if( p->pEList->nExpr!=1 ) return 0; /* Single result column */
|
|
|
|
|
if( p->pWhere ) return 0;
|
|
|
|
|
if( p->pGroupBy ) return 0;
|
|
|
|
|
if( p->pOrderBy ) return 0;
|
|
|
|
|
pExpr = p->pEList->a[0].pExpr;
|
|
|
|
|
if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */
|
|
|
|
|
assert( ExprUseUToken(pExpr) );
|
|
|
|
@ -145038,7 +145097,8 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
|
|
|
|
|
if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */
|
|
|
|
|
pSub = p->pSrc->a[0].pSelect;
|
|
|
|
|
if( pSub==0 ) return 0; /* The FROM is a subquery */
|
|
|
|
|
if( pSub->pPrior==0 ) return 0; /* Must be a compound ry */
|
|
|
|
|
if( pSub->pPrior==0 ) return 0; /* Must be a compound */
|
|
|
|
|
if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */
|
|
|
|
|
do{
|
|
|
|
|
if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */
|
|
|
|
|
if( pSub->pWhere ) return 0; /* No WHERE clause */
|
|
|
|
@ -145481,7 +145541,6 @@ SQLITE_PRIVATE int sqlite3Select(
|
|
|
|
|
&& countOfViewOptimization(pParse, p)
|
|
|
|
|
){
|
|
|
|
|
if( db->mallocFailed ) goto select_end;
|
|
|
|
|
pEList = p->pEList;
|
|
|
|
|
pTabList = p->pSrc;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
@ -146843,6 +146902,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
|
|
|
|
|
}else{
|
|
|
|
|
assert( !db->init.busy );
|
|
|
|
|
sqlite3CodeVerifySchema(pParse, iDb);
|
|
|
|
|
VVA_ONLY( pParse->ifNotExists = 1; )
|
|
|
|
|
}
|
|
|
|
|
goto trigger_cleanup;
|
|
|
|
|
}
|
|
|
|
@ -147624,7 +147684,7 @@ static void codeReturningTrigger(
|
|
|
|
|
}
|
|
|
|
|
sqlite3ExprListDelete(db, sSelect.pEList);
|
|
|
|
|
pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab);
|
|
|
|
|
if( !db->mallocFailed ){
|
|
|
|
|
if( pParse->nErr==0 ){
|
|
|
|
|
NameContext sNC;
|
|
|
|
|
memset(&sNC, 0, sizeof(sNC));
|
|
|
|
|
if( pReturning->nRetCol==0 ){
|
|
|
|
@ -148846,12 +148906,22 @@ SQLITE_PRIVATE void sqlite3Update(
|
|
|
|
|
/* Begin the database scan.
|
|
|
|
|
**
|
|
|
|
|
** Do not consider a single-pass strategy for a multi-row update if
|
|
|
|
|
** there are any triggers or foreign keys to process, or rows may
|
|
|
|
|
** be deleted as a result of REPLACE conflict handling. Any of these
|
|
|
|
|
** things might disturb a cursor being used to scan through the table
|
|
|
|
|
** or index, causing a single-pass approach to malfunction. */
|
|
|
|
|
** there is anything that might disrupt the cursor being used to do
|
|
|
|
|
** the UPDATE:
|
|
|
|
|
** (1) This is a nested UPDATE
|
|
|
|
|
** (2) There are triggers
|
|
|
|
|
** (3) There are FOREIGN KEY constraints
|
|
|
|
|
** (4) There are REPLACE conflict handlers
|
|
|
|
|
** (5) There are subqueries in the WHERE clause
|
|
|
|
|
*/
|
|
|
|
|
flags = WHERE_ONEPASS_DESIRED;
|
|
|
|
|
if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
|
|
|
|
|
if( !pParse->nested
|
|
|
|
|
&& !pTrigger
|
|
|
|
|
&& !hasFK
|
|
|
|
|
&& !chngKey
|
|
|
|
|
&& !bReplace
|
|
|
|
|
&& (sNC.ncFlags & NC_Subquery)==0
|
|
|
|
|
){
|
|
|
|
|
flags |= WHERE_ONEPASS_MULTIROW;
|
|
|
|
|
}
|
|
|
|
|
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur);
|
|
|
|
@ -150816,7 +150886,9 @@ static int vtabCallConstructor(
|
|
|
|
|
sCtx.pPrior = db->pVtabCtx;
|
|
|
|
|
sCtx.bDeclared = 0;
|
|
|
|
|
db->pVtabCtx = &sCtx;
|
|
|
|
|
pTab->nTabRef++;
|
|
|
|
|
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
|
|
|
|
|
sqlite3DeleteTable(db, pTab);
|
|
|
|
|
db->pVtabCtx = sCtx.pPrior;
|
|
|
|
|
if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
|
|
|
|
|
assert( sCtx.pTab==pTab );
|
|
|
|
@ -156848,7 +156920,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
|
|
|
|
|
pRhs = sqlite3PExpr(pParse, TK_UPLUS,
|
|
|
|
|
sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
|
|
|
|
|
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
|
|
|
|
|
if( pItem->fg.jointype & (JT_LEFT|JT_LTORJ) ){
|
|
|
|
|
if( pItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ){
|
|
|
|
|
joinType = EP_OuterON;
|
|
|
|
|
}else{
|
|
|
|
|
joinType = EP_InnerON;
|
|
|
|
@ -157985,6 +158057,10 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
|
|
|
|
|
Vdbe *v = pParse->pVdbe; /* VDBE under construction */
|
|
|
|
|
WhereLoop *pLoop = pLevel->pWLoop; /* The loop being coded */
|
|
|
|
|
int iCur; /* Cursor for table getting the filter */
|
|
|
|
|
IndexedExpr *saved_pIdxEpr; /* saved copy of Parse.pIdxEpr */
|
|
|
|
|
|
|
|
|
|
saved_pIdxEpr = pParse->pIdxEpr;
|
|
|
|
|
pParse->pIdxEpr = 0;
|
|
|
|
|
|
|
|
|
|
assert( pLoop!=0 );
|
|
|
|
|
assert( v!=0 );
|
|
|
|
@ -158041,9 +158117,8 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
|
|
|
|
|
int r1 = sqlite3GetTempRange(pParse, n);
|
|
|
|
|
int jj;
|
|
|
|
|
for(jj=0; jj<n; jj++){
|
|
|
|
|
int iCol = pIdx->aiColumn[jj];
|
|
|
|
|
assert( pIdx->pTable==pItem->pTab );
|
|
|
|
|
sqlite3ExprCodeGetColumnOfTable(v, pIdx->pTable, iCur, iCol,r1+jj);
|
|
|
|
|
sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj);
|
|
|
|
|
}
|
|
|
|
|
sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n);
|
|
|
|
|
sqlite3ReleaseTempRange(pParse, r1, n);
|
|
|
|
@ -158074,6 +158149,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
|
|
|
|
|
}
|
|
|
|
|
}while( iLevel < pWInfo->nLevel );
|
|
|
|
|
sqlite3VdbeJumpHere(v, addrOnce);
|
|
|
|
|
pParse->pIdxEpr = saved_pIdxEpr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -158373,6 +158449,7 @@ static int whereKeyStats(
|
|
|
|
|
assert( pIdx->nSample>0 );
|
|
|
|
|
assert( pRec->nField>0 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Do a binary search to find the first sample greater than or equal
|
|
|
|
|
** to pRec. If pRec contains a single field, the set of samples to search
|
|
|
|
|
** is simply the aSample[] array. If the samples in aSample[] contain more
|
|
|
|
@ -158417,7 +158494,12 @@ static int whereKeyStats(
|
|
|
|
|
** it is extended to two fields. The duplicates that this creates do not
|
|
|
|
|
** cause any problems.
|
|
|
|
|
*/
|
|
|
|
|
nField = MIN(pRec->nField, pIdx->nSample);
|
|
|
|
|
if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
|
|
|
|
|
nField = pIdx->nKeyCol;
|
|
|
|
|
}else{
|
|
|
|
|
nField = pIdx->nColumn;
|
|
|
|
|
}
|
|
|
|
|
nField = MIN(pRec->nField, nField);
|
|
|
|
|
iCol = 0;
|
|
|
|
|
iSample = pIdx->nSample * nField;
|
|
|
|
|
do{
|
|
|
|
@ -162145,6 +162227,10 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
|
|
|
|
if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
|
|
|
|
|
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
|
|
|
|
|
}
|
|
|
|
|
if( pWInfo->pSelect->pOrderBy
|
|
|
|
|
&& pWInfo->nOBSat > pWInfo->pSelect->pOrderBy->nExpr ){
|
|
|
|
|
pWInfo->nOBSat = pWInfo->pSelect->pOrderBy->nExpr;
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
pWInfo->revMask = pFrom->revLoop;
|
|
|
|
|
if( pWInfo->nOBSat<=0 ){
|
|
|
|
@ -162556,6 +162642,9 @@ static SQLITE_NOINLINE void whereAddIndexedExpr(
|
|
|
|
|
p->iIdxCur = iIdxCur;
|
|
|
|
|
p->iIdxCol = i;
|
|
|
|
|
p->bMaybeNullRow = bMaybeNullRow;
|
|
|
|
|
if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){
|
|
|
|
|
p->aff = pIdx->zColAff[i];
|
|
|
|
|
}
|
|
|
|
|
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
|
|
|
|
|
p->zIdxName = pIdx->zName;
|
|
|
|
|
#endif
|
|
|
|
@ -193018,16 +193107,18 @@ static int fts3MsrBufferData(
|
|
|
|
|
char *pList,
|
|
|
|
|
i64 nList
|
|
|
|
|
){
|
|
|
|
|
if( nList>pMsr->nBuffer ){
|
|
|
|
|
if( (nList+FTS3_NODE_PADDING)>pMsr->nBuffer ){
|
|
|
|
|
char *pNew;
|
|
|
|
|
pMsr->nBuffer = nList*2;
|
|
|
|
|
pNew = (char *)sqlite3_realloc64(pMsr->aBuffer, pMsr->nBuffer);
|
|
|
|
|
int nNew = nList*2 + FTS3_NODE_PADDING;
|
|
|
|
|
pNew = (char *)sqlite3_realloc64(pMsr->aBuffer, nNew);
|
|
|
|
|
if( !pNew ) return SQLITE_NOMEM;
|
|
|
|
|
pMsr->aBuffer = pNew;
|
|
|
|
|
pMsr->nBuffer = nNew;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert( nList>0 );
|
|
|
|
|
memcpy(pMsr->aBuffer, pList, nList);
|
|
|
|
|
memset(&pMsr->aBuffer[nList], 0, FTS3_NODE_PADDING);
|
|
|
|
|
return SQLITE_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -240171,7 +240262,7 @@ static void fts5SourceIdFunc(
|
|
|
|
|
){
|
|
|
|
|
assert( nArg==0 );
|
|
|
|
|
UNUSED_PARAM2(nArg, apUnused);
|
|
|
|
|
sqlite3_result_text(pCtx, "fts5: 2023-02-21 18:09:37 05941c2a04037fc3ed2ffae11f5d2260706f89431f463518740f72ada350866d", -1, SQLITE_TRANSIENT);
|
|
|
|
|
sqlite3_result_text(pCtx, "fts5: 2023-03-22 11:56:21 0d1fc92f94cb6b76bffe3ec34d69cffde2924203304e8ffc4155597af0c191da", -1, SQLITE_TRANSIENT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|