aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build.c11
-rw-r--r--src/expr.c3
-rw-r--r--src/func.c6
-rw-r--r--src/json.c4
-rw-r--r--src/main.c2
-rw-r--r--src/pragma.c18
-rw-r--r--src/select.c10
-rw-r--r--src/sqlite.h.in3
-rw-r--r--src/sqliteInt.h29
-rw-r--r--src/vdbe.c62
-rw-r--r--src/vdbeapi.c4
-rw-r--r--src/vtab.c2
-rw-r--r--src/where.c2
13 files changed, 120 insertions, 36 deletions
diff --git a/src/build.c b/src/build.c
index fe3a781d6..59e3e23f0 100644
--- a/src/build.c
+++ b/src/build.c
@@ -246,19 +246,14 @@ void sqlite3FinishCoding(Parse *pParse){
*/
if( pParse->pAinc ) sqlite3AutoincrementBegin(pParse);
- /* Code constant expressions that where factored out of inner loops.
- **
- ** The pConstExpr list might also contain expressions that we simply
- ** want to keep around until the Parse object is deleted. Such
- ** expressions have iConstExprReg==0. Do not generate code for
- ** those expressions, of course.
+ /* Code constant expressions that were factored out of inner loops.
*/
if( pParse->pConstExpr ){
ExprList *pEL = pParse->pConstExpr;
pParse->okConstFactor = 0;
for(i=0; i<pEL->nExpr; i++){
- int iReg = pEL->a[i].u.iConstExprReg;
- sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg);
+ assert( pEL->a[i].u.iConstExprReg>0 );
+ sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg);
}
}
diff --git a/src/expr.c b/src/expr.c
index d96f36285..9f876e610 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -5048,7 +5048,7 @@ expr_code_doover:
** once. If no functions are involved, then factor the code out and put it at
** the end of the prepared statement in the initialization section.
**
-** If regDest>=0 then the result is always stored in that register and the
+** If regDest>0 then the result is always stored in that register and the
** result is not reusable. If regDest<0 then this routine is free to
** store the value wherever it wants. The register where the expression
** is stored is returned. When regDest<0, two identical expressions might
@@ -5063,6 +5063,7 @@ int sqlite3ExprCodeRunJustOnce(
){
ExprList *p;
assert( ConstFactorOk(pParse) );
+ assert( regDest!=0 );
p = pParse->pConstExpr;
if( regDest<0 && p ){
struct ExprList_item *pItem;
diff --git a/src/func.c b/src/func.c
index 333252348..8739035b5 100644
--- a/src/func.c
+++ b/src/func.c
@@ -1907,7 +1907,8 @@ static void avgFinalize(sqlite3_context *context){
if( p && p->cnt>0 ){
double r;
if( p->approx ){
- r = p->rSum+p->rErr;
+ r = p->rSum;
+ if( !sqlite3IsNaN(p->rErr) ) r += p->rErr;
}else{
r = (double)(p->iSum);
}
@@ -1920,7 +1921,8 @@ static void totalFinalize(sqlite3_context *context){
p = sqlite3_aggregate_context(context, 0);
if( p ){
if( p->approx ){
- r = p->rSum+p->rErr;
+ r = p->rSum;
+ if( !sqlite3IsNaN(p->rErr) ) r += p->rErr;
}else{
r = (double)(p->iSum);
}
diff --git a/src/json.c b/src/json.c
index f8d4aa2a7..253fce9f4 100644
--- a/src/json.c
+++ b/src/json.c
@@ -2484,7 +2484,9 @@ static void jsonArrayLengthFunc(
}
if( pNode->eType==JSON_ARRAY ){
while( 1 /*exit-by-break*/ ){
- for(i=1; i<=pNode->n; n++){
+ i = 1;
+ while( i<=pNode->n ){
+ if( (pNode[i].jnFlags & JNODE_REMOVE)==0 ) n++;
i += jsonNodeSize(&pNode[i]);
}
if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
diff --git a/src/main.c b/src/main.c
index 6525fc0d7..d69ebf75b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2481,7 +2481,7 @@ int sqlite3_wal_checkpoint_v2(
if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_TRUNCATE ){
/* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint
** mode: */
- return SQLITE_MISUSE;
+ return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(db->mutex);
diff --git a/src/pragma.c b/src/pragma.c
index f15c1be27..a4e05bbdf 100644
--- a/src/pragma.c
+++ b/src/pragma.c
@@ -1757,8 +1757,24 @@ void sqlite3Pragma(
int r2; /* Previous key for WITHOUT ROWID tables */
int mxCol; /* Maximum non-virtual column number */
- if( !IsOrdinaryTable(pTab) ) continue;
if( pObjTab && pObjTab!=pTab ) continue;
+ if( !IsOrdinaryTable(pTab) ){
+ sqlite3_vtab *pVTab;
+ int a1;
+ if( !IsVirtual(pTab) ) continue;
+ if( pTab->u.vtab.p==0 ) continue;
+ pVTab = pTab->u.vtab.p->pVtab;
+ if( NEVER(pVTab==0) ) continue;
+ if( NEVER(pVTab->pModule==0) ) continue;
+ if( pVTab->pModule->iVersion<4 ) continue;
+ if( pVTab->pModule->xIntegrity==0 ) continue;
+ sqlite3VdbeAddOp2(v, OP_VCheck, 0, 3);
+ sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
+ a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v);
+ integrityCheckResultRow(v);
+ sqlite3VdbeJumpHere(v, a1);
+ continue;
+ }
if( isQuick || HasRowid(pTab) ){
pPk = 0;
r2 = 0;
diff --git a/src/select.c b/src/select.c
index 321badd07..90b284036 100644
--- a/src/select.c
+++ b/src/select.c
@@ -5301,12 +5301,12 @@ static int disableUnusedSubqueryResultColumns(SrcItem *pItem){
assert( pItem->pSelect!=0 );
pSub = pItem->pSelect;
assert( pSub->pEList->nExpr==pTab->nCol );
- if( (pSub->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){
- testcase( pSub->selFlags & SF_Distinct );
- testcase( pSub->selFlags & SF_Aggregate );
- return 0;
- }
for(pX=pSub; pX; pX=pX->pPrior){
+ if( (pX->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){
+ testcase( pX->selFlags & SF_Distinct );
+ testcase( pX->selFlags & SF_Aggregate );
+ return 0;
+ }
if( pX->pPrior && pX->op!=TK_ALL ){
/* This optimization does not work for compound subqueries that
** use UNION, INTERSECT, or EXCEPT. Only UNION ALL is allowed. */
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 43f45555e..2d351008d 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -7275,6 +7275,9 @@ struct sqlite3_module {
/* The methods above are in versions 1 and 2 of the sqlite_module object.
** Those below are for version 3 and greater. */
int (*xShadowName)(const char*);
+ /* The methods above are in versions 1 through 3 of the sqlite_module object.
+ ** Those below are for version 4 and greater. */
+ int (*xIntegrity)(sqlite3_vtab *pVTab, char**);
};
/*
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 785576f9c..31eac3749 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -923,16 +923,33 @@ typedef INT16_TYPE LogEst;
** using C-preprocessor macros. If that is unsuccessful, or if
** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined
** at run-time.
+**
+** If you are building SQLite on some obscure platform for which the
+** following ifdef magic does not work, you can always include either:
+**
+** -DSQLITE_BYTEORDER=1234
+**
+** or
+**
+** -DSQLITE_BYTEORDER=4321
+**
+** to cause the build to work for little-endian or big-endian processors,
+** respectively.
*/
-#ifndef SQLITE_BYTEORDER
-# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
+#ifndef SQLITE_BYTEORDER /* Replicate changes at tag-20230904a */
+# if defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
+# define SQLITE_BYTEORDER 4321
+# elif defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
+# define SQLITE_BYTEORDER 1234
+# elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1
+# define SQLITE_BYTEORDER 4321
+# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64)
-# define SQLITE_BYTEORDER 1234
-# elif defined(sparc) || defined(__ppc__) || \
- defined(__ARMEB__) || defined(__AARCH64EB__)
-# define SQLITE_BYTEORDER 4321
+# define SQLITE_BYTEORDER 1234
+# elif defined(sparc) || defined(__ARMEB__) || defined(__AARCH64EB__)
+# define SQLITE_BYTEORDER 4321
# else
# define SQLITE_BYTEORDER 0
# endif
diff --git a/src/vdbe.c b/src/vdbe.c
index 5899fa518..41e56d306 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -3641,7 +3641,6 @@ case OP_MakeRecord: {
/* NULL value. No change in zPayload */
}else{
u64 v;
- u32 i;
if( serial_type==7 ){
assert( sizeof(v)==sizeof(pRec->u.r) );
memcpy(&v, &pRec->u.r, sizeof(v));
@@ -3649,12 +3648,17 @@ case OP_MakeRecord: {
}else{
v = pRec->u.i;
}
- len = i = sqlite3SmallTypeSizes[serial_type];
- assert( i>0 );
- while( 1 /*exit-by-break*/ ){
- zPayload[--i] = (u8)(v&0xFF);
- if( i==0 ) break;
- v >>= 8;
+ len = sqlite3SmallTypeSizes[serial_type];
+ assert( len>=1 && len<=8 && len!=5 && len!=7 );
+ switch( len ){
+ default: zPayload[7] = (u8)(v&0xff); v >>= 8;
+ zPayload[6] = (u8)(v&0xff); v >>= 8;
+ case 6: zPayload[5] = (u8)(v&0xff); v >>= 8;
+ zPayload[4] = (u8)(v&0xff); v >>= 8;
+ case 4: zPayload[3] = (u8)(v&0xff); v >>= 8;
+ case 3: zPayload[2] = (u8)(v&0xff); v >>= 8;
+ case 2: zPayload[1] = (u8)(v&0xff); v >>= 8;
+ case 1: zPayload[0] = (u8)(v&0xff);
}
zPayload += len;
}
@@ -8125,6 +8129,50 @@ case OP_VOpen: { /* ncycle */
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
+/* Opcode: VCheck * P2 * P4 *
+**
+** P4 is a pointer to a Table object that is a virtual table that
+** supports the xIntegrity() method. This opcode runs the xIntegrity()
+** method for that virtual table. If an error is reported back, the error
+** message is stored in register P2. If no errors are seen, register P2
+** is set to NULL.
+*/
+case OP_VCheck: { /* out2 */
+ Table *pTab;
+ sqlite3_vtab *pVtab;
+ const sqlite3_module *pModule;
+ char *zErr = 0;
+
+ pOut = &aMem[pOp->p2];
+ sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */
+ assert( pOp->p4type==P4_TABLE );
+ pTab = pOp->p4.pTab;
+ assert( pTab!=0 );
+ assert( IsVirtual(pTab) );
+ assert( pTab->u.vtab.p!=0 );
+ pVtab = pTab->u.vtab.p->pVtab;
+ assert( pVtab!=0 );
+ pModule = pVtab->pModule;
+ assert( pModule!=0 );
+ assert( pModule->iVersion>=4 );
+ assert( pModule->xIntegrity!=0 );
+ pTab->nTabRef++;
+ sqlite3VtabLock(pTab->u.vtab.p);
+ rc = pModule->xIntegrity(pVtab, &zErr);
+ sqlite3VtabUnlock(pTab->u.vtab.p);
+ sqlite3DeleteTable(db, pTab);
+ if( rc ){
+ sqlite3_free(zErr);
+ goto abort_due_to_error;
+ }
+ if( zErr ){
+ sqlite3VdbeMemSetStr(pOut, zErr, -1, SQLITE_UTF8, sqlite3_free);
+ }
+ break;
+}
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VInitIn P1 P2 P3 * *
** Synopsis: r[P2]=ValueList(P1,P3)
**
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index 79b5de9f0..1213dbe6d 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -907,7 +907,7 @@ static int valueFromValueList(
ValueList *pRhs;
*ppOut = 0;
- if( pVal==0 ) return SQLITE_MISUSE;
+ if( pVal==0 ) return SQLITE_MISUSE_BKPT;
if( (pVal->flags & MEM_Dyn)==0 || pVal->xDel!=sqlite3VdbeValueListFree ){
return SQLITE_ERROR;
}else{
@@ -1508,7 +1508,7 @@ static int vdbeUnbind(Vdbe *p, unsigned int i){
}
sqlite3_mutex_enter(p->db->mutex);
if( p->eVdbeState!=VDBE_READY_STATE ){
- sqlite3Error(p->db, SQLITE_MISUSE);
+ sqlite3Error(p->db, SQLITE_MISUSE_BKPT);
sqlite3_mutex_leave(p->db->mutex);
sqlite3_log(SQLITE_MISUSE,
"bind on a busy prepared statement: [%s]", p->zSql);
diff --git a/src/vtab.c b/src/vtab.c
index 741518991..a9cfcb9d7 100644
--- a/src/vtab.c
+++ b/src/vtab.c
@@ -821,7 +821,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
sqlite3_mutex_enter(db->mutex);
pCtx = db->pVtabCtx;
if( !pCtx || pCtx->bDeclared ){
- sqlite3Error(db, SQLITE_MISUSE);
+ sqlite3Error(db, SQLITE_MISUSE_BKPT);
sqlite3_mutex_leave(db->mutex);
return SQLITE_MISUSE_BKPT;
}
diff --git a/src/where.c b/src/where.c
index 213df4223..01ae180ae 100644
--- a/src/where.c
+++ b/src/where.c
@@ -4097,7 +4097,7 @@ int sqlite3_vtab_rhs_value(
sqlite3_value *pVal = 0;
int rc = SQLITE_OK;
if( iCons<0 || iCons>=pIdxInfo->nConstraint ){
- rc = SQLITE_MISUSE; /* EV: R-30545-25046 */
+ rc = SQLITE_MISUSE_BKPT; /* EV: R-30545-25046 */
}else{
if( pH->aRhs[iCons]==0 ){
WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset];