Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
sqlite: update to 3.46.1
Baptiste Daroussin committed 1 year ago
commit 361b114f895ba89b7a32505ebee7f117cac09a8a
parent bf7b278
3 files changed +105 -95
modified external/sqlite/shell.c
@@ -605,11 +605,6 @@ zSkipValidUtf8(const char *z, int nAccept, long ccm);
#endif

#if CIO_WIN_WC_XLATE
-
/* Character used to represent a known-incomplete UTF-8 char group (�) */
-
static WCHAR cBadGroup = 0xfffd;
-
#endif
-

-
#if CIO_WIN_WC_XLATE
static HANDLE handleOfFile(FILE *pf){
  int fileDesc = _fileno(pf);
  union { intptr_t osfh; HANDLE fh; } fid = {
@@ -12547,7 +12542,7 @@ static int expertFilter(
  pCsr->pData = 0;
  if( rc==SQLITE_OK ){
    rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg,
-
        "SELECT * FROM main.%Q WHERE sample()", pVtab->pTab->zName
+
        "SELECT * FROM main.%Q WHERE sqlite_expert_sample()", pVtab->pTab->zName
    );
  }

@@ -13421,7 +13416,7 @@ struct IdxRemCtx {
};

/*
-
** Implementation of scalar function rem().
+
** Implementation of scalar function sqlite_expert_rem().
*/
static void idxRemFunc(
  sqlite3_context *pCtx,
@@ -13434,7 +13429,7 @@ static void idxRemFunc(
  assert( argc==2 );

  iSlot = sqlite3_value_int(argv[0]);
-
  assert( iSlot<=p->nSlot );
+
  assert( iSlot<p->nSlot );
  pSlot = &p->aSlot[iSlot];

  switch( pSlot->eType ){
@@ -13545,7 +13540,8 @@ static int idxPopulateOneStat1(
    const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0);
    const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1);
    zCols = idxAppendText(&rc, zCols, 
-
        "%sx.%Q IS rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl
+
        "%sx.%Q IS sqlite_expert_rem(%d, x.%Q) COLLATE %s", 
+
        zComma, zName, nCol, zName, zColl
    );
    zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol);
  }
@@ -13678,13 +13674,13 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){

  if( rc==SQLITE_OK ){
    sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
-
    rc = sqlite3_create_function(
-
        dbrem, "rem", 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0
+
    rc = sqlite3_create_function(dbrem, "sqlite_expert_rem", 
+
        2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0
    );
  }
  if( rc==SQLITE_OK ){
-
    rc = sqlite3_create_function(
-
        p->db, "sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0
+
    rc = sqlite3_create_function(p->db, "sqlite_expert_sample", 
+
        0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0
    );
  }

@@ -13736,6 +13732,9 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
    rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0);
  }

+
  sqlite3_create_function(p->db, "sqlite_expert_rem", 2, SQLITE_UTF8, 0,0,0,0);
+
  sqlite3_create_function(p->db, "sqlite_expert_sample", 0,SQLITE_UTF8,0,0,0,0);
+

  sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
  return rc;
}
@@ -16836,8 +16835,8 @@ static int recoverError(
  va_start(ap, zFmt);
  if( zFmt ){
    z = sqlite3_vmprintf(zFmt, ap);
-
    va_end(ap);
  }
+
  va_end(ap);
  sqlite3_free(p->zErrMsg);
  p->zErrMsg = z;
  p->errCode = errCode;
@@ -27085,7 +27084,6 @@ static int do_meta_command(char *zLine, ShellState *p){
      import_cleanup(&sCtx);
      shell_out_of_memory();
    }
-
    nByte = strlen(zSql);    
    rc =  sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
    sqlite3_free(zSql);
    zSql = 0;
@@ -27104,16 +27102,21 @@ static int do_meta_command(char *zLine, ShellState *p){
    sqlite3_finalize(pStmt);
    pStmt = 0;
    if( nCol==0 ) return 0; /* no columns, no error */
-
    zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
+

+
    nByte = 64                 /* space for "INSERT INTO", "VALUES(", ")\0" */
+
          + (zSchema ? strlen(zSchema)*2 + 2: 0)  /* Quoted schema name */
+
          + strlen(zTable)*2 + 2                  /* Quoted table name */
+
          + nCol*2;            /* Space for ",?" for each column */
+
    zSql = sqlite3_malloc64( nByte );
    if( zSql==0 ){
      import_cleanup(&sCtx);
      shell_out_of_memory();
    }
    if( zSchema ){
-
      sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\".\"%w\" VALUES(?", 
+
      sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\".\"%w\" VALUES(?", 
                       zSchema, zTable);
    }else{
-
      sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
+
      sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
    }
    j = strlen30(zSql);
    for(i=1; i<nCol; i++){
@@ -27122,6 +27125,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    }
    zSql[j++] = ')';
    zSql[j] = 0;
+
    assert( j<nByte );
    if( eVerbose>=2 ){
      oputf("Insert using: %s\n", zSql);
    }
modified external/sqlite/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-
** version 3.46.0.  By combining all the individual C code files into this
+
** version 3.46.1.  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
@@ -18,7 +18,7 @@
** separate file. This file contains only code for the core SQLite library.
**
** The content in this amalgamation comes from Fossil check-in
-
** 96c92aba00c8375bc32fafcdf12429c58bd8.
+
** c9c2ab54ba1f5f46360f1b4f35d849cd3f08.
*/
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
@@ -459,9 +459,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-
#define SQLITE_VERSION        "3.46.0"
-
#define SQLITE_VERSION_NUMBER 3046000
-
#define SQLITE_SOURCE_ID      "2024-05-23 13:25:27 96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e"
+
#define SQLITE_VERSION        "3.46.1"
+
#define SQLITE_VERSION_NUMBER 3046001
+
#define SQLITE_SOURCE_ID      "2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33"

/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -19361,7 +19361,7 @@ struct SrcList {
#define WHERE_AGG_DISTINCT     0x0400 /* Query is "SELECT agg(DISTINCT ...)" */
#define WHERE_ORDERBY_LIMIT    0x0800 /* ORDERBY+LIMIT on the inner loop */
#define WHERE_RIGHT_JOIN       0x1000 /* Processing a RIGHT JOIN */
-
                        /*     0x2000    not currently used */
+
#define WHERE_KEEP_ALL_JOINS   0x2000 /* Do not do the omit-noop-join opt */
#define WHERE_USE_LIMIT        0x4000 /* Use the LIMIT in cost estimates */
                        /*     0x8000    not currently used */

@@ -90173,7 +90173,8 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff
  assert( iVar>0 );
  if( v ){
    Mem *pMem = &v->aVar[iVar-1];
-
    assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
+
    assert( (v->db->flags & SQLITE_EnableQPSG)==0
+
         || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 );
    if( 0==(pMem->flags & MEM_Null) ){
      sqlite3_value *pRet = sqlite3ValueNew(v->db);
      if( pRet ){
@@ -90193,7 +90194,8 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff
*/
SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
  assert( iVar>0 );
-
  assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
+
  assert( (v->db->flags & SQLITE_EnableQPSG)==0
+
       || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 );
  if( iVar>=32 ){
    v->expmask |= 0x80000000;
  }else{
@@ -106950,7 +106952,7 @@ static void extendFJMatch(
static SQLITE_NOINLINE int isValidSchemaTableName(
  const char *zTab,         /* Name as it appears in the SQL */
  Table *pTab,              /* The schema table we are trying to match */
-
  Schema *pSchema           /* non-NULL if a database qualifier is present */
+
  const char *zDb           /* non-NULL if a database qualifier is present */
){
  const char *zLegacy;
  assert( pTab!=0 );
@@ -106961,7 +106963,7 @@ static SQLITE_NOINLINE int isValidSchemaTableName(
    if( sqlite3StrICmp(zTab+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){
      return 1;
    }
-
    if( pSchema==0 ) return 0;
+
    if( zDb==0 ) return 0;
    if( sqlite3StrICmp(zTab+7, &LEGACY_SCHEMA_TABLE[7])==0 ) return 1;
    if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1;
  }else{
@@ -107144,7 +107146,7 @@ static int lookupName(
            }
          }else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){
            if( pTab->tnum!=1 ) continue;
-
            if( !isValidSchemaTableName(zTab, pTab, pSchema) ) continue;
+
            if( !isValidSchemaTableName(zTab, pTab, zDb) ) continue;
          }
          assert( ExprUseYTab(pExpr) );
          if( IN_RENAME_OBJECT && pItem->zAlias ){
@@ -108876,6 +108878,9 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
** Resolve all names for all expression in an expression list.  This is
** just like sqlite3ResolveExprNames() except that it works for an expression
** list rather than a single expression.
+
**
+
** The return value is SQLITE_OK (0) for success or SQLITE_ERROR (1) for a
+
** failure.
*/
SQLITE_PRIVATE int sqlite3ResolveExprListNames(
  NameContext *pNC,       /* Namespace to resolve expressions in. */
@@ -108884,7 +108889,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames(
  int i;
  int savedHasAgg = 0;
  Walker w;
-
  if( pList==0 ) return WRC_Continue;
+
  if( pList==0 ) return SQLITE_OK;
  w.pParse = pNC->pParse;
  w.xExprCallback = resolveExprStep;
  w.xSelectCallback = resolveSelectStep;
@@ -108898,7 +108903,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames(
#if SQLITE_MAX_EXPR_DEPTH>0
    w.pParse->nHeight += pExpr->nHeight;
    if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){
-
      return WRC_Abort;
+
      return SQLITE_ERROR;
    }
#endif
    sqlite3WalkExprNN(&w, pExpr);
@@ -108915,10 +108920,10 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames(
                          (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg);
      pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg);
    }
-
    if( w.pParse->nErr>0 ) return WRC_Abort;
+
    if( w.pParse->nErr>0 ) return SQLITE_ERROR;
  }
  pNC->ncFlags |= savedHasAgg;
-
  return WRC_Continue;
+
  return SQLITE_OK;
}

/*
@@ -117457,7 +117462,7 @@ static int renameResolveTrigger(Parse *pParse){
  /* ALWAYS() because if the table of the trigger does not exist, the
  ** error would have been hit before this point */
  if( ALWAYS(pParse->pTriggerTab) ){
-
    rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab);
+
    rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab)!=0;
  }

  /* Resolve symbols in WHEN clause */
@@ -124426,8 +124431,9 @@ create_view_fail:
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
/*
** The Table structure pTable is really a VIEW.  Fill in the names of
-
** the columns of the view in the pTable structure.  Return the number
-
** of errors.  If an error is seen leave an error message in pParse->zErrMsg.
+
** the columns of the view in the pTable structure.  Return non-zero if
+
** there are errors.  If an error is seen an error message is left
+
** in pParse->zErrMsg.
*/
static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){
  Table *pSelTab;   /* A fake table from which we get the result set */
@@ -124550,7 +124556,7 @@ static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){
    sqlite3DeleteColumnNames(db, pTable);
  }
#endif /* SQLITE_OMIT_VIEW */
-
  return nErr;
+
  return nErr + pParse->nErr;
}
SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
  assert( pTable!=0 );
@@ -130848,6 +130854,8 @@ static void groupConcatValue(sqlite3_context *context){
      sqlite3_result_error_toobig(context);
    }else if( pAccum->accError==SQLITE_NOMEM ){
      sqlite3_result_error_nomem(context);
+
    }else if( pGCC->nAccum>0 && pAccum->nChar==0 ){
+
      sqlite3_result_text(context, "", 1, SQLITE_STATIC);
    }else{
      const char *zText = sqlite3_str_value(pAccum);
      sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT);
@@ -133602,6 +133610,7 @@ SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList
        pRet->pSrc->nSrc = 1;
        pRet->pPrior = pLeft->pPrior;
        pRet->op = pLeft->op;
+
        if( pRet->pPrior ) pRet->selFlags |= SF_Values;
        pLeft->pPrior = 0;
        pLeft->op = TK_SELECT;
        assert( pLeft->pNext==0 );
@@ -166067,7 +166076,9 @@ static int whereLoopAddBtree(
                  " according to whereIsCoveringIndex()\n", pProbe->zName));
            }
          }
-
        }else if( m==0 ){
+
        }else if( m==0
+
           && (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700))
+
        ){
          WHERETRACE(0x200,
             ("-> %s a covering index according to bitmasks\n",
             pProbe->zName, m==0 ? "is" : "is not"));
@@ -167956,6 +167967,10 @@ static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){
**      the right-most table of a subquery that was flattened into the
**      main query and that subquery was the right-hand operand of an
**      inner join that held an ON or USING clause.
+
**   6) The ORDER BY clause has 63 or fewer terms
+
**   7) The omit-noop-join optimization is enabled.
+
**
+
** Items (1), (6), and (7) are checked by the caller.
**
** For example, given:
**
@@ -168369,6 +168384,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
  if( pOrderBy && pOrderBy->nExpr>=BMS ){
    pOrderBy = 0;
    wctrlFlags &= ~WHERE_WANT_DISTINCT;
+
    wctrlFlags |= WHERE_KEEP_ALL_JOINS; /* Disable omit-noop-join opt */
  }

  /* The number of tables in the FROM clause is limited by the number of
@@ -168669,10 +168685,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
  ** in-line sqlite3WhereCodeOneLoopStart() for performance reasons.
  */
  notReady = ~(Bitmask)0;
-
  if( pWInfo->nLevel>=2
-
   && pResultSet!=0                         /* these two combine to guarantee */
-
   && 0==(wctrlFlags & WHERE_AGG_DISTINCT)  /* condition (1) above */
-
   && OptimizationEnabled(db, SQLITE_OmitNoopJoin)
+
  if( pWInfo->nLevel>=2       /* Must be a join, or this opt8n is pointless */
+
   && pResultSet!=0           /* Condition (1) */
+
   && 0==(wctrlFlags & (WHERE_AGG_DISTINCT|WHERE_KEEP_ALL_JOINS)) /* (1),(6) */
+
   && OptimizationEnabled(db, SQLITE_OmitNoopJoin)                /* (7) */
  ){
    notReady = whereOmitNoopJoin(pWInfo, notReady);
    nTabList = pWInfo->nLevel;
@@ -168992,26 +169008,6 @@ whereBeginError:
  }
#endif

-
#ifdef SQLITE_DEBUG
-
/*
-
** Return true if cursor iCur is opened by instruction k of the
-
** bytecode.  Used inside of assert() only.
-
*/
-
static int cursorIsOpen(Vdbe *v, int iCur, int k){
-
  while( k>=0 ){
-
    VdbeOp *pOp = sqlite3VdbeGetOp(v,k--);
-
    if( pOp->p1!=iCur ) continue;
-
    if( pOp->opcode==OP_Close ) return 0;
-
    if( pOp->opcode==OP_OpenRead ) return 1;
-
    if( pOp->opcode==OP_OpenWrite ) return 1;
-
    if( pOp->opcode==OP_OpenDup ) return 1;
-
    if( pOp->opcode==OP_OpenAutoindex ) return 1;
-
    if( pOp->opcode==OP_OpenEphemeral ) return 1;
-
  }
-
  return 0;
-
}
-
#endif /* SQLITE_DEBUG */
-

/*
** Generate the end of the WHERE loop.  See comments on
** sqlite3WhereBegin() for additional information.
@@ -169311,16 +169307,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
            ** reference.  Verify that this is harmless - that the
            ** table being referenced really is open.
            */
-
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
-
            assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
-
                 || cursorIsOpen(v,pOp->p1,k)
-
                 || pOp->opcode==OP_Offset
-
            );
-
#else
-
            assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
-
                 || cursorIsOpen(v,pOp->p1,k)
-
            );
-
#endif
+
            if( pLoop->wsFlags & WHERE_IDX_ONLY ){
+
              sqlite3ErrorMsg(pParse, "internal query planner error");
+
              pParse->rc = SQLITE_INTERNAL;
+
            }
          }
        }else if( pOp->opcode==OP_Rowid ){
          pOp->p1 = pLevel->iIdxCur;
@@ -172591,9 +172581,9 @@ static void updateDeleteLimitError(
          break;
        }
      }
-
      if( (p->selFlags & SF_MultiValue)==0 &&
-
        (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
-
        cnt>mxSelect
+
      if( (p->selFlags & (SF_MultiValue|SF_Values))==0
+
       && (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0
+
       && cnt>mxSelect
      ){
        sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
      }
@@ -237004,7 +236994,11 @@ static int sqlite3Fts5ExprNew(
  }

  sqlite3_free(sParse.apPhrase);
-
  *pzErr = sParse.zErr;
+
  if( 0==*pzErr ){
+
    *pzErr = sParse.zErr;
+
  }else{
+
    sqlite3_free(sParse.zErr);
+
  }
  return sParse.rc;
}

@@ -239132,6 +239126,7 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
    assert( pRight->eType==FTS5_STRING
        || pRight->eType==FTS5_TERM
        || pRight->eType==FTS5_EOF
+
        || (pRight->eType==FTS5_AND && pParse->bPhraseToAnd)
    );

    if( pLeft->eType==FTS5_AND ){
@@ -251299,6 +251294,7 @@ static int fts5UpdateMethod(
        rc = SQLITE_ERROR;
      }else{
        rc = fts5SpecialDelete(pTab, apVal);
+
        bUpdateOrDelete = 1;
      }
    }else{
      rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
@@ -252473,14 +252469,16 @@ static int sqlite3Fts5GetTokenizer(
  if( pMod==0 ){
    assert( nArg>0 );
    rc = SQLITE_ERROR;
-
    *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
+
    if( pzErr ) *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
  }else{
    rc = pMod->x.xCreate(
        pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok
    );
    pConfig->pTokApi = &pMod->x;
    if( rc!=SQLITE_OK ){
-
      if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor");
+
      if( pzErr && rc!=SQLITE_NOMEM ){
+
        *pzErr = sqlite3_mprintf("error in tokenizer constructor");
+
      }
    }else{
      pConfig->ePattern = sqlite3Fts5TokenizerPattern(
          pMod->x.xCreate, pConfig->pTok
@@ -252539,7 +252537,7 @@ static void fts5SourceIdFunc(
){
  assert( nArg==0 );
  UNUSED_PARAM2(nArg, apUnused);
-
  sqlite3_result_text(pCtx, "fts5: 2024-05-23 13:25:27 96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e", -1, SQLITE_TRANSIENT);
+
  sqlite3_result_text(pCtx, "fts5: 2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33", -1, SQLITE_TRANSIENT);
}

/*
@@ -252574,17 +252572,23 @@ static int fts5IntegrityMethod(

  assert( pzErr!=0 && *pzErr==0 );
  UNUSED_PARAM(isQuick);
+
  assert( pTab->p.pConfig->pzErrmsg==0 );
+
  pTab->p.pConfig->pzErrmsg = pzErr;
  rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, 0);
-
  if( (rc&0xff)==SQLITE_CORRUPT ){
-
    *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s",
-
                zSchema, zTabname);
-
     rc = (*pzErr) ? SQLITE_OK : SQLITE_NOMEM;
-
  }else if( rc!=SQLITE_OK ){
-
    *pzErr = sqlite3_mprintf("unable to validate the inverted index for"
-
                             " FTS5 table %s.%s: %s",
-
                zSchema, zTabname, sqlite3_errstr(rc));
+
  if( *pzErr==0 && rc!=SQLITE_OK ){
+
    if( (rc&0xff)==SQLITE_CORRUPT ){
+
      *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s",
+
          zSchema, zTabname);
+
      rc = (*pzErr) ? SQLITE_OK : SQLITE_NOMEM;
+
    }else{
+
      *pzErr = sqlite3_mprintf("unable to validate the inverted index for"
+
          " FTS5 table %s.%s: %s",
+
          zSchema, zTabname, sqlite3_errstr(rc));
+
    }
  }
+

  sqlite3Fts5IndexCloseReader(pTab->p.pIndex);
+
  pTab->p.pConfig->pzErrmsg = 0;

  return rc;
}
@@ -254018,7 +254022,7 @@ static int fts5AsciiCreate(
      int i;
      memset(p, 0, sizeof(AsciiTokenizer));
      memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
-
      for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
+
      for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
        const char *zArg = azArg[i+1];
        if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
          fts5AsciiAddExceptions(p, zArg, 1);
@@ -254029,6 +254033,7 @@ static int fts5AsciiCreate(
          rc = SQLITE_ERROR;
        }
      }
+
      if( rc==SQLITE_OK && i<nArg ) rc = SQLITE_ERROR;
      if( rc!=SQLITE_OK ){
        fts5AsciiDelete((Fts5Tokenizer*)p);
        p = 0;
@@ -254320,17 +254325,16 @@ static int fts5UnicodeCreate(
      }

      /* Search for a "categories" argument */
-
      for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
+
      for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
        if( 0==sqlite3_stricmp(azArg[i], "categories") ){
          zCat = azArg[i+1];
        }
      }
-

      if( rc==SQLITE_OK ){
        rc = unicodeSetCategories(p, zCat);
      }

-
      for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
+
      for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
        const char *zArg = azArg[i+1];
        if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
          if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
@@ -254355,6 +254359,7 @@ static int fts5UnicodeCreate(
          rc = SQLITE_ERROR;
        }
      }
+
      if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR;

    }else{
      rc = SQLITE_NOMEM;
@@ -255237,7 +255242,7 @@ static int fts5TriCreate(
    int i;
    pNew->bFold = 1;
    pNew->iFoldParam = 0;
-
    for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
+
    for(i=0; rc==SQLITE_OK && i<nArg-1; i+=2){
      const char *zArg = azArg[i+1];
      if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
        if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
@@ -255255,6 +255260,7 @@ static int fts5TriCreate(
        rc = SQLITE_ERROR;
      }
    }
+
    if( i<nArg && rc==SQLITE_OK ) rc = SQLITE_ERROR;

    if( pNew->iFoldParam!=0 && pNew->bFold==0 ){
      rc = SQLITE_ERROR;
modified external/sqlite/sqlite3.h
@@ -146,9 +146,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-
#define SQLITE_VERSION        "3.46.0"
-
#define SQLITE_VERSION_NUMBER 3046000
-
#define SQLITE_SOURCE_ID      "2024-05-23 13:25:27 96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e"
+
#define SQLITE_VERSION        "3.46.1"
+
#define SQLITE_VERSION_NUMBER 3046001
+
#define SQLITE_SOURCE_ID      "2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33"

/*
** CAPI3REF: Run-Time Library Version Numbers