SQLite

Check-in [c623d9a5]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:The sqlite3FaultSim(300) error from [1e8863909ac369e5] must be treated as an OOM, since it simulates an OOM. Also fix deferred deletion of Expr objects from [a53bdd311c4154fd] so that it does not corrupt the AST if an OOM occurs.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | cleanup-testing
Files: files | file ages | folders
SHA3-256: c623d9a51e0ae6b4a8e1186714d14e7aa3df55246e123323481f07f07749dea5
User & Date: drh 2024-05-10 18:10:34
Context
2024-05-10
18:15
Add a test for the fixes on this branch. (Closed-Leaf check-in: 716088d6 user: dan tags: cleanup-testing)
18:10
The sqlite3FaultSim(300) error from [1e8863909ac369e5] must be treated as an OOM, since it simulates an OOM. Also fix deferred deletion of Expr objects from [a53bdd311c4154fd] so that it does not corrupt the AST if an OOM occurs. (check-in: c623d9a5 user: drh tags: cleanup-testing)
17:05
Improvements to the ".testctrl fault_install" command in the CLI. (check-in: 48b34ded user: drh tags: cleanup-testing)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
/*
** Arrange to cause pExpr to be deleted when the pParse is deleted.
** This is similar to sqlite3ExprDelete() except that the delete is
** deferred until the pParse is deleted.
**
** The pExpr might be deleted immediately on an OOM error.
**
** The deferred delete is (currently) implemented by adding the
** pExpr to the pParse->pConstExpr list with a register number of 0.
*/
void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){
  sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr);
}

/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
** expression.
*/
void sqlite3ExprUnmapAndDelete(Parse *pParse, Expr *p){
  if( p ){







|
|

|
|







1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
/*
** Arrange to cause pExpr to be deleted when the pParse is deleted.
** This is similar to sqlite3ExprDelete() except that the delete is
** deferred until the pParse is deleted.
**
** The pExpr might be deleted immediately on an OOM error.
**
** Return 0 if the delete was successfully deferred.  Return non-zero
** if the delete happened immediately because of an OOM.
*/
int sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){
  return 0==sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr);
}

/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
** expression.
*/
void sqlite3ExprUnmapAndDelete(Parse *pParse, Expr *p){
  if( p ){
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
    sqlite3 *db = pParse->db;
    assert( iAgg>=0 );
    if( pExpr->op!=TK_AGG_FUNCTION ){
      if( iAgg<pAggInfo->nColumn
       && pAggInfo->aCol[iAgg].pCExpr==pExpr
      ){
        pExpr = sqlite3ExprDup(db, pExpr, 0);
        if( pExpr ){
          pAggInfo->aCol[iAgg].pCExpr = pExpr;
          sqlite3ExprDeferredDelete(pParse, pExpr);
        }
      }
    }else{
      assert( pExpr->op==TK_AGG_FUNCTION );
      if( ALWAYS(iAgg<pAggInfo->nFunc)
       && pAggInfo->aFunc[iAgg].pFExpr==pExpr
      ){
        pExpr = sqlite3ExprDup(db, pExpr, 0);
        if( pExpr ){
          pAggInfo->aFunc[iAgg].pFExpr = pExpr;
          sqlite3ExprDeferredDelete(pParse, pExpr);
        }
      }
    }
  }
  return WRC_Continue;
}








|

<








|

<







6677
6678
6679
6680
6681
6682
6683
6684
6685

6686
6687
6688
6689
6690
6691
6692
6693
6694
6695

6696
6697
6698
6699
6700
6701
6702
    sqlite3 *db = pParse->db;
    assert( iAgg>=0 );
    if( pExpr->op!=TK_AGG_FUNCTION ){
      if( iAgg<pAggInfo->nColumn
       && pAggInfo->aCol[iAgg].pCExpr==pExpr
      ){
        pExpr = sqlite3ExprDup(db, pExpr, 0);
        if( pExpr && !sqlite3ExprDeferredDelete(pParse, pExpr) ){
          pAggInfo->aCol[iAgg].pCExpr = pExpr;

        }
      }
    }else{
      assert( pExpr->op==TK_AGG_FUNCTION );
      if( ALWAYS(iAgg<pAggInfo->nFunc)
       && pAggInfo->aFunc[iAgg].pFExpr==pExpr
      ){
        pExpr = sqlite3ExprDup(db, pExpr, 0);
        if( pExpr && !sqlite3ExprDeferredDelete(pParse, pExpr) ){
          pAggInfo->aFunc[iAgg].pFExpr = pExpr;

        }
      }
    }
  }
  return WRC_Continue;
}

Changes to src/prepare.c.

632
633
634
635
636
637
638

639
640
641
642
643
644
645
  Parse *pParse,                      /* Destroy when this Parser finishes */
  void (*xCleanup)(sqlite3*,void*),   /* The cleanup routine */
  void *pPtr                          /* Pointer to object to be cleaned up */
){
  ParseCleanup *pCleanup;
  if( sqlite3FaultSim(300) ){
    pCleanup = 0;

  }else{
    pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup));
  }
  if( pCleanup ){
    pCleanup->pNext = pParse->pCleanup;
    pParse->pCleanup = pCleanup;
    pCleanup->pPtr = pPtr;







>







632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
  Parse *pParse,                      /* Destroy when this Parser finishes */
  void (*xCleanup)(sqlite3*,void*),   /* The cleanup routine */
  void *pPtr                          /* Pointer to object to be cleaned up */
){
  ParseCleanup *pCleanup;
  if( sqlite3FaultSim(300) ){
    pCleanup = 0;
    sqlite3OomFault(pParse->db);
  }else{
    pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup));
  }
  if( pCleanup ){
    pCleanup->pNext = pParse->pCleanup;
    pParse->pCleanup = pCleanup;
    pCleanup->pPtr = pPtr;

Changes to src/sqliteInt.h.

4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
Expr *sqlite3ExprFunction(Parse*,ExprList*, const Token*, int);
void sqlite3ExprAddFunctionOrderBy(Parse*,Expr*,ExprList*);
void sqlite3ExprOrderByAggregateError(Parse*,Expr*);
void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
void sqlite3ExprDelete(sqlite3*, Expr*);
void sqlite3ExprDeleteGeneric(sqlite3*,void*);
void sqlite3ExprDeferredDelete(Parse*, Expr*);
void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
Select *sqlite3ExprListToValues(Parse*, int, ExprList*);
void sqlite3ExprListSetSortOrder(ExprList*,int,int);
void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int);
void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);







|







4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
Expr *sqlite3ExprFunction(Parse*,ExprList*, const Token*, int);
void sqlite3ExprAddFunctionOrderBy(Parse*,Expr*,ExprList*);
void sqlite3ExprOrderByAggregateError(Parse*,Expr*);
void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
void sqlite3ExprDelete(sqlite3*, Expr*);
void sqlite3ExprDeleteGeneric(sqlite3*,void*);
int sqlite3ExprDeferredDelete(Parse*, Expr*);
void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
Select *sqlite3ExprListToValues(Parse*, int, ExprList*);
void sqlite3ExprListSetSortOrder(ExprList*,int,int);
void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int);
void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);