better-sqlite3-multiple-ciphers 7.5.1-beta.3 → 7.5.2-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -92,7 +92,7 @@ extern SQLITE_API LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
92
92
  /*** Begin of #include "sqlite3patched.c" ***/
93
93
  /******************************************************************************
94
94
  ** This file is an amalgamation of many separate C source files from SQLite
95
- ** version 3.38.1. By combining all the individual C code files into this
95
+ ** version 3.38.3. By combining all the individual C code files into this
96
96
  ** single large file, the entire code can be compiled as a single translation
97
97
  ** unit. This allows many compilers to do optimizations that would not be
98
98
  ** possible if the files were compiled separately. Performance improvements
@@ -544,9 +544,9 @@ extern "C" {
544
544
  ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
545
545
  ** [sqlite_version()] and [sqlite_source_id()].
546
546
  */
547
- #define SQLITE_VERSION "3.38.1"
548
- #define SQLITE_VERSION_NUMBER 3038001
549
- #define SQLITE_SOURCE_ID "2022-03-12 13:37:29 38c210fdd258658321c85ec9c01a072fda3ada94540e3239d29b34dc547a8cbc"
547
+ #define SQLITE_VERSION "3.38.3"
548
+ #define SQLITE_VERSION_NUMBER 3038003
549
+ #define SQLITE_SOURCE_ID "2022-04-27 12:03:15 9547e2c38a1c6f751a77d4d796894dec4dc5d8f5d79b1cd39e1ffc50df7b3be4"
550
550
 
551
551
  /*
552
552
  ** CAPI3REF: Run-Time Library Version Numbers
@@ -20028,6 +20028,7 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
20028
20028
  SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
20029
20029
  SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
20030
20030
  SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int);
20031
+ SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr*,const SrcItem*);
20031
20032
  #ifdef SQLITE_ENABLE_CURSOR_HINTS
20032
20033
  SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*);
20033
20034
  #endif
@@ -29436,8 +29437,9 @@ SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const cha
29436
29437
  ** Free any prior content in *pz and replace it with a copy of zNew.
29437
29438
  */
29438
29439
  SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
29440
+ char *z = sqlite3DbStrDup(db, zNew);
29439
29441
  sqlite3DbFree(db, *pz);
29440
- *pz = sqlite3DbStrDup(db, zNew);
29442
+ *pz = z;
29441
29443
  }
29442
29444
 
29443
29445
  /*
@@ -39790,11 +39792,17 @@ static int unixShmLock(
39790
39792
  int flags /* What to do with the lock */
39791
39793
  ){
39792
39794
  unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */
39793
- unixShm *p = pDbFd->pShm; /* The shared memory being locked */
39794
- unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */
39795
+ unixShm *p; /* The shared memory being locked */
39796
+ unixShmNode *pShmNode; /* The underlying file iNode */
39795
39797
  int rc = SQLITE_OK; /* Result code */
39796
39798
  u16 mask; /* Mask of locks to take or release */
39797
- int *aLock = pShmNode->aLock;
39799
+ int *aLock;
39800
+
39801
+ p = pDbFd->pShm;
39802
+ if( p==0 ) return SQLITE_IOERR_SHMLOCK;
39803
+ pShmNode = p->pShmNode;
39804
+ if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK;
39805
+ aLock = pShmNode->aLock;
39798
39806
 
39799
39807
  assert( pShmNode==pDbFd->pInode->pShmNode );
39800
39808
  assert( pShmNode->pInode==pDbFd->pInode );
@@ -47082,10 +47090,14 @@ static int winShmLock(
47082
47090
  winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */
47083
47091
  winShm *p = pDbFd->pShm; /* The shared memory being locked */
47084
47092
  winShm *pX; /* For looping over all siblings */
47085
- winShmNode *pShmNode = p->pShmNode;
47093
+ winShmNode *pShmNode;
47086
47094
  int rc = SQLITE_OK; /* Result code */
47087
47095
  u16 mask; /* Mask of locks to take or release */
47088
47096
 
47097
+ if( p==0 ) return SQLITE_IOERR_SHMLOCK;
47098
+ pShmNode = p->pShmNode;
47099
+ if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK;
47100
+
47089
47101
  assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
47090
47102
  assert( n>=1 );
47091
47103
  assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
@@ -67853,6 +67865,8 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
67853
67865
  ** fragmented bytes within the page. */
67854
67866
  memcpy(&aData[iAddr], &aData[pc], 2);
67855
67867
  aData[hdr+7] += (u8)x;
67868
+ testcase( pc+x>maxPC );
67869
+ return &aData[pc];
67856
67870
  }else if( x+pc > maxPC ){
67857
67871
  /* This slot extends off the end of the usable part of the page */
67858
67872
  *pRc = SQLITE_CORRUPT_PAGE(pPg);
@@ -72052,7 +72066,7 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto(
72052
72066
  assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
72053
72067
  assert( pPage->isInit );
72054
72068
  if( pPage->leaf ){
72055
- assert( pCur->ix<pCur->pPage->nCell );
72069
+ assert( pCur->ix<pCur->pPage->nCell || CORRUPT_DB );
72056
72070
  pCur->ix = (u16)idx;
72057
72071
  *pRes = c;
72058
72072
  rc = SQLITE_OK;
@@ -74576,7 +74590,7 @@ static int balance_nonroot(
74576
74590
  iOvflSpace += sz;
74577
74591
  assert( sz<=pBt->maxLocal+23 );
74578
74592
  assert( iOvflSpace <= (int)pBt->pageSize );
74579
- for(k=0; b.ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
74593
+ for(k=0; b.ixNx[k]<=j && ALWAYS(k<NB*2); k++){}
74580
74594
  pSrcEnd = b.apEnd[k];
74581
74595
  if( SQLITE_WITHIN(pSrcEnd, pCell, pCell+sz) ){
74582
74596
  rc = SQLITE_CORRUPT_BKPT;
@@ -75092,24 +75106,6 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
75092
75106
  assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags );
75093
75107
  assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 );
75094
75108
 
75095
- if( pCur->eState==CURSOR_FAULT ){
75096
- assert( pCur->skipNext!=SQLITE_OK );
75097
- return pCur->skipNext;
75098
- }
75099
-
75100
- assert( cursorOwnsBtShared(pCur) );
75101
- assert( (pCur->curFlags & BTCF_WriteFlag)!=0
75102
- && pBt->inTransaction==TRANS_WRITE
75103
- && (pBt->btsFlags & BTS_READ_ONLY)==0 );
75104
- assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
75105
-
75106
- /* Assert that the caller has been consistent. If this cursor was opened
75107
- ** expecting an index b-tree, then the caller should be inserting blob
75108
- ** keys with no associated data. If the cursor was opened expecting an
75109
- ** intkey table, the caller should be inserting integer keys with a
75110
- ** blob of associated data. */
75111
- assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) );
75112
-
75113
75109
  /* Save the positions of any other cursors open on this table.
75114
75110
  **
75115
75111
  ** In some cases, the call to btreeMoveto() below is a no-op. For
@@ -75134,6 +75130,24 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
75134
75130
  }
75135
75131
  }
75136
75132
 
75133
+ if( pCur->eState>=CURSOR_REQUIRESEEK ){
75134
+ rc = moveToRoot(pCur);
75135
+ if( rc && rc!=SQLITE_EMPTY ) return rc;
75136
+ }
75137
+
75138
+ assert( cursorOwnsBtShared(pCur) );
75139
+ assert( (pCur->curFlags & BTCF_WriteFlag)!=0
75140
+ && pBt->inTransaction==TRANS_WRITE
75141
+ && (pBt->btsFlags & BTS_READ_ONLY)==0 );
75142
+ assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
75143
+
75144
+ /* Assert that the caller has been consistent. If this cursor was opened
75145
+ ** expecting an index b-tree, then the caller should be inserting blob
75146
+ ** keys with no associated data. If the cursor was opened expecting an
75147
+ ** intkey table, the caller should be inserting integer keys with a
75148
+ ** blob of associated data. */
75149
+ assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) );
75150
+
75137
75151
  if( pCur->pKeyInfo==0 ){
75138
75152
  assert( pX->pKey==0 );
75139
75153
  /* If this is an insert into a table b-tree, invalidate any incrblob
@@ -75222,8 +75236,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
75222
75236
  }
75223
75237
  }
75224
75238
  assert( pCur->eState==CURSOR_VALID
75225
- || (pCur->eState==CURSOR_INVALID && loc)
75226
- || CORRUPT_DB );
75239
+ || (pCur->eState==CURSOR_INVALID && loc) );
75227
75240
 
75228
75241
  pPage = pCur->pPage;
75229
75242
  assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) );
@@ -75510,12 +75523,16 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
75510
75523
  assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
75511
75524
  assert( !hasReadConflicts(p, pCur->pgnoRoot) );
75512
75525
  assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
75513
- if( pCur->eState==CURSOR_REQUIRESEEK ){
75514
- rc = btreeRestoreCursorPosition(pCur);
75515
- assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
75516
- if( rc || pCur->eState!=CURSOR_VALID ) return rc;
75526
+ if( pCur->eState!=CURSOR_VALID ){
75527
+ if( pCur->eState>=CURSOR_REQUIRESEEK ){
75528
+ rc = btreeRestoreCursorPosition(pCur);
75529
+ assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
75530
+ if( rc || pCur->eState!=CURSOR_VALID ) return rc;
75531
+ }else{
75532
+ return SQLITE_CORRUPT_BKPT;
75533
+ }
75517
75534
  }
75518
- assert( CORRUPT_DB || pCur->eState==CURSOR_VALID );
75535
+ assert( pCur->eState==CURSOR_VALID );
75519
75536
 
75520
75537
  iCellDepth = pCur->iPage;
75521
75538
  iCellIdx = pCur->ix;
@@ -78138,7 +78155,11 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
78138
78155
  assert( !sqlite3VdbeMemIsRowSet(pMem) );
78139
78156
  assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
78140
78157
  || desiredEnc==SQLITE_UTF16BE );
78141
- if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
78158
+ if( !(pMem->flags&MEM_Str) ){
78159
+ pMem->enc = desiredEnc;
78160
+ return SQLITE_OK;
78161
+ }
78162
+ if( pMem->enc==desiredEnc ){
78142
78163
  return SQLITE_OK;
78143
78164
  }
78144
78165
  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
@@ -104845,6 +104866,38 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
104845
104866
  return exprIsConst(p, 3, iCur);
104846
104867
  }
104847
104868
 
104869
+ /*
104870
+ ** Check pExpr to see if it is an invariant constraint on data source pSrc.
104871
+ ** This is an optimization. False negatives will perhaps cause slower
104872
+ ** queries, but false positives will yield incorrect answers. So when in
104873
+ ** double, return 0.
104874
+ **
104875
+ ** To be an invariant constraint, the following must be true:
104876
+ **
104877
+ ** (1) pExpr cannot refer to any table other than pSrc->iCursor.
104878
+ **
104879
+ ** (2) pExpr cannot use subqueries or non-deterministic functions.
104880
+ **
104881
+ ** (*) ** Not applicable to this branch **
104882
+ **
104883
+ ** (4) If pSrc is the right operand of a LEFT JOIN, then...
104884
+ ** (4a) pExpr must come from an ON clause..
104885
+ ** (4b) and specifically the ON clause associated with the LEFT JOIN.
104886
+ **
104887
+ ** (5) If pSrc is not the right operand of a LEFT JOIN or the left
104888
+ ** operand of a RIGHT JOIN, then pExpr must be from the WHERE
104889
+ ** clause, not an ON clause.
104890
+ */
104891
+ SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){
104892
+ if( pSrc->fg.jointype & JT_LEFT ){
104893
+ if( !ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (4a) */
104894
+ if( pExpr->w.iRightJoinTable!=pSrc->iCursor ) return 0; /* rule (4b) */
104895
+ }else{
104896
+ if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (5) */
104897
+ }
104898
+ return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */
104899
+ }
104900
+
104848
104901
 
104849
104902
  /*
104850
104903
  ** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy().
@@ -125202,7 +125255,7 @@ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
125202
125255
  }
125203
125256
 
125204
125257
  for(i=j=0; i<pTab->nCol; i++){
125205
- assert( pTab->aCol[i].affinity!=0 );
125258
+ assert( pTab->aCol[i].affinity!=0 || sqlite3VdbeParser(v)->nErr>0 );
125206
125259
  if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){
125207
125260
  zColAff[j++] = pTab->aCol[i].affinity;
125208
125261
  }
@@ -133643,7 +133696,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl
133643
133696
  sqlite3ResetAllSchemasOfConnection(db);
133644
133697
  pDb = &db->aDb[iDb];
133645
133698
  }else
133646
- if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
133699
+ if( rc==SQLITE_OK || ((db->flags&SQLITE_NoSchemaError) && rc!=SQLITE_NOMEM)){
133647
133700
  /* Hack: If the SQLITE_NoSchemaError flag is set, then consider
133648
133701
  ** the schema loaded, even if errors (other than OOM) occurred. In
133649
133702
  ** this situation the current sqlite3_prepare() operation will fail,
@@ -139133,8 +139186,7 @@ static int pushDownWhereTerms(
139133
139186
  Parse *pParse, /* Parse context (for malloc() and error reporting) */
139134
139187
  Select *pSubq, /* The subquery whose WHERE clause is to be augmented */
139135
139188
  Expr *pWhere, /* The WHERE clause of the outer query */
139136
- int iCursor, /* Cursor number of the subquery */
139137
- int isLeftJoin /* True if pSubq is the right term of a LEFT JOIN */
139189
+ SrcItem *pSrc /* The subquery term of the outer FROM clause */
139138
139190
  ){
139139
139191
  Expr *pNew;
139140
139192
  int nChng = 0;
@@ -139169,10 +139221,11 @@ static int pushDownWhereTerms(
139169
139221
  return 0; /* restriction (3) */
139170
139222
  }
139171
139223
  while( pWhere->op==TK_AND ){
139172
- nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight,
139173
- iCursor, isLeftJoin);
139224
+ nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrc);
139174
139225
  pWhere = pWhere->pLeft;
139175
139226
  }
139227
+
139228
+ #if 0 /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */
139176
139229
  if( isLeftJoin
139177
139230
  && (ExprHasProperty(pWhere,EP_FromJoin)==0
139178
139231
  || pWhere->w.iRightJoinTable!=iCursor)
@@ -139184,7 +139237,9 @@ static int pushDownWhereTerms(
139184
139237
  ){
139185
139238
  return 0; /* restriction (5) */
139186
139239
  }
139187
- if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
139240
+ #endif
139241
+
139242
+ if( sqlite3ExprIsTableConstraint(pWhere, pSrc) ){
139188
139243
  nChng++;
139189
139244
  pSubq->selFlags |= SF_PushDown;
139190
139245
  while( pSubq ){
@@ -139192,8 +139247,8 @@ static int pushDownWhereTerms(
139192
139247
  pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
139193
139248
  unsetJoinExpr(pNew, -1);
139194
139249
  x.pParse = pParse;
139195
- x.iTable = iCursor;
139196
- x.iNewTable = iCursor;
139250
+ x.iTable = pSrc->iCursor;
139251
+ x.iNewTable = pSrc->iCursor;
139197
139252
  x.isLeftJoin = 0;
139198
139253
  x.pEList = pSubq->pEList;
139199
139254
  pNew = substExpr(&x, pNew);
@@ -140975,8 +141030,7 @@ SQLITE_PRIVATE int sqlite3Select(
140975
141030
  if( OptimizationEnabled(db, SQLITE_PushDown)
140976
141031
  && (pItem->fg.isCte==0
140977
141032
  || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2))
140978
- && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor,
140979
- (pItem->fg.jointype & JT_OUTER)!=0)
141033
+ && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem)
140980
141034
  ){
140981
141035
  #if SELECTTRACE_ENABLED
140982
141036
  if( sqlite3SelectTrace & 0x100 ){
@@ -146389,6 +146443,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
146389
146443
 
146390
146444
  sqlite3ParseObjectInit(&sParse, db);
146391
146445
  sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
146446
+ sParse.disableTriggers = 1;
146392
146447
  /* We should never be able to reach this point while loading the
146393
146448
  ** schema. Nevertheless, defend against that (turn off db->init.busy)
146394
146449
  ** in case a bug arises. */
@@ -152900,8 +152955,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
152900
152955
  ** WHERE clause (or the ON clause of a LEFT join) that constrain which
152901
152956
  ** rows of the target table (pSrc) that can be used. */
152902
152957
  if( (pTerm->wtFlags & TERM_VIRTUAL)==0
152903
- && ((pSrc->fg.jointype&JT_LEFT)==0 || ExprHasProperty(pExpr,EP_FromJoin))
152904
- && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor)
152958
+ && sqlite3ExprIsTableConstraint(pExpr, pSrc)
152905
152959
  ){
152906
152960
  pPartial = sqlite3ExprAnd(pParse, pPartial,
152907
152961
  sqlite3ExprDup(pParse->db, pExpr, 0));
@@ -153140,7 +153194,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
153140
153194
  for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){
153141
153195
  Expr *pExpr = pTerm->pExpr;
153142
153196
  if( (pTerm->wtFlags & TERM_VIRTUAL)==0
153143
- && sqlite3ExprIsTableConstant(pExpr, iCur)
153197
+ && sqlite3ExprIsTableConstraint(pExpr, pItem)
153144
153198
  ){
153145
153199
  sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
153146
153200
  }
@@ -154686,8 +154740,17 @@ static void whereLoopOutputAdjust(
154686
154740
  /* If there are extra terms in the WHERE clause not used by an index
154687
154741
  ** that depend only on the table being scanned, and that will tend to
154688
154742
  ** cause many rows to be omitted, then mark that table as
154689
- ** "self-culling". */
154690
- pLoop->wsFlags |= WHERE_SELFCULL;
154743
+ ** "self-culling".
154744
+ **
154745
+ ** 2022-03-24: Self-culling only applies if either the extra terms
154746
+ ** are straight comparison operators that are non-true with NULL
154747
+ ** operand, or if the loop is not a LEFT JOIN.
154748
+ */
154749
+ if( (pTerm->eOperator & 0x3f)!=0
154750
+ || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0
154751
+ ){
154752
+ pLoop->wsFlags |= WHERE_SELFCULL;
154753
+ }
154691
154754
  }
154692
154755
  if( pTerm->truthProb<=0 ){
154693
154756
  /* If a truth probability is specified using the likelihood() hints,
@@ -157986,6 +158049,26 @@ whereBeginError:
157986
158049
  }
157987
158050
  #endif
157988
158051
 
158052
+ #ifdef SQLITE_DEBUG
158053
+ /*
158054
+ ** Return true if cursor iCur is opened by instruction k of the
158055
+ ** bytecode. Used inside of assert() only.
158056
+ */
158057
+ static int cursorIsOpen(Vdbe *v, int iCur, int k){
158058
+ while( k>=0 ){
158059
+ VdbeOp *pOp = sqlite3VdbeGetOp(v,k--);
158060
+ if( pOp->p1!=iCur ) continue;
158061
+ if( pOp->opcode==OP_Close ) return 0;
158062
+ if( pOp->opcode==OP_OpenRead ) return 1;
158063
+ if( pOp->opcode==OP_OpenWrite ) return 1;
158064
+ if( pOp->opcode==OP_OpenDup ) return 1;
158065
+ if( pOp->opcode==OP_OpenAutoindex ) return 1;
158066
+ if( pOp->opcode==OP_OpenEphemeral ) return 1;
158067
+ }
158068
+ return 0;
158069
+ }
158070
+ #endif /* SQLITE_DEBUG */
158071
+
157989
158072
  /*
157990
158073
  ** Generate the end of the WHERE loop. See comments on
157991
158074
  ** sqlite3WhereBegin() for additional information.
@@ -158238,14 +158321,15 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
158238
158321
  ){
158239
158322
  int x = pOp->p2;
158240
158323
  assert( pIdx->pTable==pTab );
158324
+ #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
158325
+ if( pOp->opcode==OP_Offset ){
158326
+ /* Do not need to translate the column number */
158327
+ }else
158328
+ #endif
158241
158329
  if( !HasRowid(pTab) ){
158242
158330
  Index *pPk = sqlite3PrimaryKeyIndex(pTab);
158243
158331
  x = pPk->aiColumn[x];
158244
158332
  assert( x>=0 );
158245
- #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
158246
- }else if( pOp->opcode==OP_Offset ){
158247
- /* Do not need to translate the column number */
158248
- #endif
158249
158333
  }else{
158250
158334
  testcase( x!=sqlite3StorageColumnToTable(pTab,x) );
158251
158335
  x = sqlite3StorageColumnToTable(pTab,x);
@@ -158255,9 +158339,22 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
158255
158339
  pOp->p2 = x;
158256
158340
  pOp->p1 = pLevel->iIdxCur;
158257
158341
  OpcodeRewriteTrace(db, k, pOp);
158342
+ }else{
158343
+ /* Unable to translate the table reference into an index
158344
+ ** reference. Verify that this is harmless - that the
158345
+ ** table being referenced really is open.
158346
+ */
158347
+ #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
158348
+ assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
158349
+ || cursorIsOpen(v,pOp->p1,k)
158350
+ || pOp->opcode==OP_Offset
158351
+ );
158352
+ #else
158353
+ assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
158354
+ || cursorIsOpen(v,pOp->p1,k)
158355
+ );
158356
+ #endif
158258
158357
  }
158259
- assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0
158260
- || pWInfo->eOnePass );
158261
158358
  }else if( pOp->opcode==OP_Rowid ){
158262
158359
  pOp->p1 = pLevel->iIdxCur;
158263
158360
  pOp->opcode = OP_IdxRowid;
@@ -160017,7 +160114,7 @@ static void windowAggStep(
160017
160114
 
160018
160115
  for(iEnd=sqlite3VdbeCurrentAddr(v); iOp<iEnd; iOp++){
160019
160116
  VdbeOp *pOp = sqlite3VdbeGetOp(v, iOp);
160020
- if( pOp->opcode==OP_Column && pOp->p1==pWin->iEphCsr ){
160117
+ if( pOp->opcode==OP_Column && pOp->p1==pMWin->iEphCsr ){
160021
160118
  pOp->p1 = csr;
160022
160119
  }
160023
160120
  }
@@ -194340,14 +194437,15 @@ static JsonNode *jsonLookupStep(
194340
194437
  *pzErr = zPath;
194341
194438
  return 0;
194342
194439
  }
194440
+ testcase( nKey==0 );
194343
194441
  }else{
194344
194442
  zKey = zPath;
194345
194443
  for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
194346
194444
  nKey = i;
194347
- }
194348
- if( nKey==0 ){
194349
- *pzErr = zPath;
194350
- return 0;
194445
+ if( nKey==0 ){
194446
+ *pzErr = zPath;
194447
+ return 0;
194448
+ }
194351
194449
  }
194352
194450
  j = 1;
194353
194451
  for(;;){
@@ -195495,6 +195593,33 @@ static int jsonEachNext(sqlite3_vtab_cursor *cur){
195495
195593
  return SQLITE_OK;
195496
195594
  }
195497
195595
 
195596
+ /* Append an object label to the JSON Path being constructed
195597
+ ** in pStr.
195598
+ */
195599
+ static void jsonAppendObjectPathElement(
195600
+ JsonString *pStr,
195601
+ JsonNode *pNode
195602
+ ){
195603
+ int jj, nn;
195604
+ const char *z;
195605
+ assert( pNode->eType==JSON_STRING );
195606
+ assert( pNode->jnFlags & JNODE_LABEL );
195607
+ assert( pNode->eU==1 );
195608
+ z = pNode->u.zJContent;
195609
+ nn = pNode->n;
195610
+ assert( nn>=2 );
195611
+ assert( z[0]=='"' );
195612
+ assert( z[nn-1]=='"' );
195613
+ if( nn>2 && sqlite3Isalpha(z[1]) ){
195614
+ for(jj=2; jj<nn-1 && sqlite3Isalnum(z[jj]); jj++){}
195615
+ if( jj==nn-1 ){
195616
+ z++;
195617
+ nn -= 2;
195618
+ }
195619
+ }
195620
+ jsonPrintf(nn+2, pStr, ".%.*s", nn, z);
195621
+ }
195622
+
195498
195623
  /* Append the name of the path for element i to pStr
195499
195624
  */
195500
195625
  static void jsonEachComputePath(
@@ -195519,10 +195644,7 @@ static void jsonEachComputePath(
195519
195644
  }else{
195520
195645
  assert( pUp->eType==JSON_OBJECT );
195521
195646
  if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
195522
- assert( pNode->eType==JSON_STRING );
195523
- assert( pNode->jnFlags & JNODE_LABEL );
195524
- assert( pNode->eU==1 );
195525
- jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
195647
+ jsonAppendObjectPathElement(pStr, pNode);
195526
195648
  }
195527
195649
  }
195528
195650
 
@@ -195593,8 +195715,7 @@ static int jsonEachColumn(
195593
195715
  if( p->eType==JSON_ARRAY ){
195594
195716
  jsonPrintf(30, &x, "[%d]", p->iRowid);
195595
195717
  }else if( p->eType==JSON_OBJECT ){
195596
- assert( pThis->eU==1 );
195597
- jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
195718
+ jsonAppendObjectPathElement(&x, pThis);
195598
195719
  }
195599
195720
  }
195600
195721
  jsonResult(&x);
@@ -234485,7 +234606,7 @@ static void fts5SourceIdFunc(
234485
234606
  ){
234486
234607
  assert( nArg==0 );
234487
234608
  UNUSED_PARAM2(nArg, apUnused);
234488
- sqlite3_result_text(pCtx, "fts5: 2022-03-12 13:37:29 38c210fdd258658321c85ec9c01a072fda3ada94540e3239d29b34dc547a8cbc", -1, SQLITE_TRANSIENT);
234609
+ sqlite3_result_text(pCtx, "fts5: 2022-04-27 12:03:15 9547e2c38a1c6f751a77d4d796894dec4dc5d8f5d79b1cd39e1ffc50df7b3be4", -1, SQLITE_TRANSIENT);
234489
234610
  }
234490
234611
 
234491
234612
  /*
@@ -239613,10 +239734,10 @@ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
239613
239734
  #define SQLITE3MC_VERSION_H_
239614
239735
 
239615
239736
  #define SQLITE3MC_VERSION_MAJOR 1
239616
- #define SQLITE3MC_VERSION_MINOR 3
239617
- #define SQLITE3MC_VERSION_RELEASE 9
239737
+ #define SQLITE3MC_VERSION_MINOR 4
239738
+ #define SQLITE3MC_VERSION_RELEASE 2
239618
239739
  #define SQLITE3MC_VERSION_SUBRELEASE 0
239619
- #define SQLITE3MC_VERSION_STRING "SQLite3 Multiple Ciphers 1.3.9"
239740
+ #define SQLITE3MC_VERSION_STRING "SQLite3 Multiple Ciphers 1.4.2"
239620
239741
 
239621
239742
  #endif /* SQLITE3MC_VERSION_H_ */
239622
239743
  /*** End of #include "sqlite3mc_version.h" ***/
@@ -239775,9 +239896,9 @@ extern "C" {
239775
239896
  ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
239776
239897
  ** [sqlite_version()] and [sqlite_source_id()].
239777
239898
  */
239778
- #define SQLITE_VERSION "3.38.1"
239779
- #define SQLITE_VERSION_NUMBER 3038001
239780
- #define SQLITE_SOURCE_ID "2022-03-12 13:37:29 38c210fdd258658321c85ec9c01a072fda3ada94540e3239d29b34dc547a8cbc"
239899
+ #define SQLITE_VERSION "3.38.3"
239900
+ #define SQLITE_VERSION_NUMBER 3038003
239901
+ #define SQLITE_SOURCE_ID "2022-04-27 12:03:15 9547e2c38a1c6f751a77d4d796894dec4dc5d8f5d79b1cd39e1ffc50df7b3be4"
239781
239902
 
239782
239903
  /*
239783
239904
  ** CAPI3REF: Run-Time Library Version Numbers
@@ -262304,6 +262425,26 @@ sqlite3mcFileControlPragma(sqlite3* db, const char* zDbName, int op, void* pArg)
262304
262425
  ((char**)pArg)[0] = sqlite3_mprintf("ok");
262305
262426
  }
262306
262427
  }
262428
+ else if (sqlite3StrICmp(pragmaName, "hexkey") == 0)
262429
+ {
262430
+ int nValue = sqlite3Strlen30(pragmaValue);
262431
+ if (((nValue & 1) == 0) && (sqlite3mcIsHexKey(pragmaValue, nValue) != 0))
262432
+ {
262433
+ char* zHexKey = sqlite3_malloc(nValue/2);
262434
+ sqlite3mcConvertHex2Bin(pragmaValue, nValue, zHexKey);
262435
+ rc = sqlite3_key_v2(db, zDbName, zHexKey, nValue/2);
262436
+ sqlite3_free(zHexKey);
262437
+ if (rc == SQLITE_OK)
262438
+ {
262439
+ ((char**)pArg)[0] = sqlite3_mprintf("ok");
262440
+ }
262441
+ }
262442
+ else
262443
+ {
262444
+ rc = SQLITE_ERROR;
262445
+ ((char**)pArg)[0] = sqlite3_mprintf("Malformed hex string");
262446
+ }
262447
+ }
262307
262448
  else if (sqlite3StrICmp(pragmaName, "rekey") == 0)
262308
262449
  {
262309
262450
  rc = sqlite3_rekey_v2(db, zDbName, pragmaValue, -1);
@@ -262323,6 +262464,37 @@ sqlite3mcFileControlPragma(sqlite3* db, const char* zDbName, int op, void* pArg)
262323
262464
  }
262324
262465
  }
262325
262466
  }
262467
+ else if (sqlite3StrICmp(pragmaName, "hexrekey") == 0)
262468
+ {
262469
+ int nValue = sqlite3Strlen30(pragmaValue);
262470
+ if (((nValue & 1) == 0) && (sqlite3mcIsHexKey(pragmaValue, nValue) != 0))
262471
+ {
262472
+ char* zHexKey = sqlite3_malloc(nValue/2);
262473
+ sqlite3mcConvertHex2Bin(pragmaValue, nValue, zHexKey);
262474
+ rc = sqlite3_rekey_v2(db, zDbName, zHexKey, nValue/2);
262475
+ sqlite3_free(zHexKey);
262476
+ if (rc == SQLITE_OK)
262477
+ {
262478
+ ((char**)pArg)[0] = sqlite3_mprintf("ok");
262479
+ }
262480
+ else
262481
+ {
262482
+ if (db->pErr)
262483
+ {
262484
+ const char* z = (const char*)sqlite3_value_text(db->pErr);
262485
+ if (z && sqlite3Strlen30(z) > 0)
262486
+ {
262487
+ ((char**)pArg)[0] = sqlite3_mprintf(z);
262488
+ }
262489
+ }
262490
+ }
262491
+ }
262492
+ else
262493
+ {
262494
+ rc = SQLITE_ERROR;
262495
+ ((char**)pArg)[0] = sqlite3_mprintf("Malformed hex string");
262496
+ }
262497
+ }
262326
262498
  else
262327
262499
  {
262328
262500
  int j;
@@ -262387,13 +262559,15 @@ sqlite3mcCodecQueryParameters(sqlite3* db, const char* zDb, const char* zUri)
262387
262559
  {
262388
262560
  u8 iByte;
262389
262561
  int i;
262390
- char zDecoded[40];
262391
- for (i = 0, iByte = 0; i < sizeof(zDecoded) * 2 && sqlite3Isxdigit(zKey[i]); i++)
262562
+ int nKey = sqlite3Strlen30(zKey);
262563
+ char* zDecoded = sqlite3_malloc(nKey);
262564
+ for (i = 0, iByte = 0; i < nKey && sqlite3Isxdigit(zKey[i]); i++)
262392
262565
  {
262393
262566
  iByte = (iByte << 4) + sqlite3HexToInt(zKey[i]);
262394
- if ((i & 1) != 0) zDecoded[i / 2] = iByte;
262567
+ if ((i & 1) != 0) zDecoded[i/2] = iByte;
262395
262568
  }
262396
- sqlite3_key_v2(db, zDb, zDecoded, i / 2);
262569
+ sqlite3_key_v2(db, zDb, zDecoded, i/2);
262570
+ sqlite3_free(zDecoded);
262397
262571
  }
262398
262572
  else if ((zKey = sqlite3_uri_parameter(zUri, "key")) != 0)
262399
262573
  {
@@ -262471,7 +262645,7 @@ sqlite3mcHandleMainKey(sqlite3* db, const char* zPath)
262471
262645
  ** Purpose: Implementation of SQLite codec API
262472
262646
  ** Author: Ulrich Telle
262473
262647
  ** Created: 2006-12-06
262474
- ** Copyright: (c) 2006-2021 Ulrich Telle
262648
+ ** Copyright: (c) 2006-2022 Ulrich Telle
262475
262649
  ** License: MIT
262476
262650
  */
262477
262651
 
@@ -262547,7 +262721,7 @@ sqlite3mcBtreeSetPageSize(Btree* p, int pageSize, int nReserve, int iFix)
262547
262721
  ** Change 4: Call sqlite3mcBtreeSetPageSize instead of sqlite3BtreeSetPageSize for main database
262548
262722
  ** (sqlite3mcBtreeSetPageSize allows to reduce the number of reserved bytes)
262549
262723
  **
262550
- ** This code is generated by the script rekeyvacuum.sh from SQLite version 3.38.1 amalgamation.
262724
+ ** This code is generated by the script rekeyvacuum.sh from SQLite version 3.38.3 amalgamation.
262551
262725
  */
262552
262726
  SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3mcRunVacuumForRekey(
262553
262727
  char **pzErrMsg, /* Write error message here */
@@ -262939,7 +263113,7 @@ SQLITE_PRIVATE Codec*
262939
263113
  sqlite3mcGetMainCodec(sqlite3* db);
262940
263114
 
262941
263115
  SQLITE_PRIVATE void
262942
- sqlite3mcSetCodec(sqlite3* db, const char* zFileName, Codec* codec);
263116
+ sqlite3mcSetCodec(sqlite3* db, const char* zDbName, const char* zFileName, Codec* codec);
262943
263117
 
262944
263118
  static int
262945
263119
  mcAdjustBtree(Btree* pBt, int nPageSize, int nReserved, int isLegacy)
@@ -263001,7 +263175,7 @@ sqlite3mcCodecAttach(sqlite3* db, int nDb, const char* zPath, const void* zKey,
263001
263175
  sqlite3mcSetBtree(codec, db->aDb[nDb].pBt);
263002
263176
  mcAdjustBtree(db->aDb[nDb].pBt, pageSize, reserved, sqlite3mcGetLegacyWriteCipher(codec));
263003
263177
  sqlite3mcCodecSizeChange(codec, pageSize, reserved);
263004
- sqlite3mcSetCodec(db, dbFileName, codec);
263178
+ sqlite3mcSetCodec(db, zDbName, dbFileName, codec);
263005
263179
  }
263006
263180
  else
263007
263181
  {
@@ -263022,7 +263196,7 @@ sqlite3mcCodecAttach(sqlite3* db, int nDb, const char* zPath, const void* zKey,
263022
263196
  /* Remove codec for main database */
263023
263197
  if (nDb == 0 && nKey == 0)
263024
263198
  {
263025
- sqlite3mcSetCodec(db, dbFileName, NULL);
263199
+ sqlite3mcSetCodec(db, zDbName, dbFileName, NULL);
263026
263200
  }
263027
263201
  }
263028
263202
  }
@@ -263057,7 +263231,7 @@ sqlite3mcCodecAttach(sqlite3* db, int nDb, const char* zPath, const void* zKey,
263057
263231
  int reserved = sqlite3mcGetReservedWriteCipher(codec);
263058
263232
  mcAdjustBtree(db->aDb[nDb].pBt, pageSize, reserved, sqlite3mcGetLegacyWriteCipher(codec));
263059
263233
  sqlite3mcCodecSizeChange(codec, pageSize, reserved);
263060
- sqlite3mcSetCodec(db, dbFileName, codec);
263234
+ sqlite3mcSetCodec(db, zDbName, dbFileName, codec);
263061
263235
  }
263062
263236
  else
263063
263237
  {
@@ -263204,7 +263378,7 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey)
263204
263378
  int nReservedWriteCipher;
263205
263379
  sqlite3mcSetHasReadCipher(codec, 0); /* Original database is not encrypted */
263206
263380
  mcAdjustBtree(pBt, sqlite3mcGetPageSizeWriteCipher(codec), sqlite3mcGetReservedWriteCipher(codec), sqlite3mcGetLegacyWriteCipher(codec));
263207
- sqlite3mcSetCodec(db, dbFileName, codec);
263381
+ sqlite3mcSetCodec(db, zDbName, dbFileName, codec);
263208
263382
  nReservedWriteCipher = sqlite3mcGetReservedWriteCipher(codec);
263209
263383
  sqlite3mcCodecSizeChange(codec, nPagesize, nReservedWriteCipher);
263210
263384
  if (nReserved != nReservedWriteCipher)
@@ -263355,7 +263529,7 @@ leave_rekey:
263355
263529
  if (!sqlite3mcIsEncrypted(codec))
263356
263530
  {
263357
263531
  /* Remove codec for unencrypted database */
263358
- sqlite3mcSetCodec(db, dbFileName, NULL);
263532
+ sqlite3mcSetCodec(db, zDbName, dbFileName, NULL);
263359
263533
  }
263360
263534
  return rc;
263361
263535
  }
@@ -267303,6 +267477,15 @@ SQLITE_EXTENSION_INIT1
267303
267477
  #include <stdio.h>
267304
267478
  #include <math.h>
267305
267479
 
267480
+ #ifdef SQLITE_HAVE_ZLIB
267481
+ #include <zlib.h>
267482
+ #define fopen gzopen
267483
+ #define fclose gzclose
267484
+ #define fread gzfread
267485
+ #define fseek gzseek
267486
+ #define ftell gztell
267487
+ #endif
267488
+
267306
267489
  #ifndef SQLITE_OMIT_VIRTUALTABLE
267307
267490
 
267308
267491
  /*
@@ -267334,7 +267517,11 @@ SQLITE_EXTENSION_INIT1
267334
267517
  typedef struct VsvReader VsvReader;
267335
267518
  struct VsvReader
267336
267519
  {
267520
+ #ifdef SQLITE_HAVE_ZLIB
267521
+ gzFile in; /* Read the VSV text from this compressed input stream */
267522
+ #else
267337
267523
  FILE *in; /* Read the VSV text from this input stream */
267524
+ #endif
267338
267525
  char *z; /* Accumulated text for a field */
267339
267526
  int n; /* Number of bytes in z */
267340
267527
  int nAlloc; /* Space allocated for z[] */
@@ -268234,6 +268421,7 @@ static int vsvtabConnect(
268234
268421
  }
268235
268422
  else if (nCol<0)
268236
268423
  {
268424
+ nCol = 0;
268237
268425
  do
268238
268426
  {
268239
268427
  vsv_read_one_field(&sRdr);
@@ -273243,7 +273431,7 @@ int sqlite3_regexp_init(
273243
273431
  ** Purpose: Implementation of SQLite VFS for Multiple Ciphers
273244
273432
  ** Author: Ulrich Telle
273245
273433
  ** Created: 2020-02-28
273246
- ** Copyright: (c) 2020-2021 Ulrich Telle
273434
+ ** Copyright: (c) 2020-2022 Ulrich Telle
273247
273435
  ** License: MIT
273248
273436
  */
273249
273437
 
@@ -273272,6 +273460,7 @@ struct sqlite3mc_file
273272
273460
  {
273273
273461
  sqlite3_file base; /* sqlite3_file I/O methods */
273274
273462
  sqlite3_file* pFile; /* Real underlying OS file */
273463
+ sqlite3mc_vfs* pVfsMC; /* Pointer to the sqlite3mc_vfs object */
273275
273464
  const char* zFileName; /* File name */
273276
273465
  int openFlags; /* Open flags */
273277
273466
  sqlite3mc_file* pMainNext; /* Next main db file */
@@ -273294,9 +273483,6 @@ struct sqlite3mc_vfs
273294
273483
  #define REALVFS(p) ((sqlite3_vfs*)(((sqlite3mc_vfs*)(p))->base.pAppData))
273295
273484
  #define REALFILE(p) (((sqlite3mc_file*)(p))->pFile)
273296
273485
 
273297
- #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
273298
- #define ORIGFILE(p) ((sqlite3_file*)(((CksmFile*)(p))+1))
273299
-
273300
273486
  /*
273301
273487
  ** Prototypes for VFS methods
273302
273488
  */
@@ -273350,37 +273536,8 @@ static const int walFrameHeaderSize = 24;
273350
273536
  static const int walFileHeaderSize = 32;
273351
273537
 
273352
273538
  /*
273353
- ** Global VFS structure of SQLite3 Multiple Ciphers VFS
273539
+ ** Global I/O method structure of SQLite3 Multiple Ciphers VFS
273354
273540
  */
273355
- static sqlite3mc_vfs mcVfsGlobal =
273356
- {
273357
- {
273358
- 3, /* iVersion */
273359
- 0, /* szOsFile */
273360
- 1024, /* mxPathname */
273361
- 0, /* pNext */
273362
- SQLITE3MC_VFS_NAME, /* zName */
273363
- 0, /* pAppData */
273364
- mcVfsOpen, /* xOpen */
273365
- mcVfsDelete, /* xDelete */
273366
- mcVfsAccess, /* xAccess */
273367
- mcVfsFullPathname, /* xFullPathname */
273368
- mcVfsDlOpen, /* xDlOpen */
273369
- mcVfsDlError, /* xDlError */
273370
- mcVfsDlSym, /* xDlSym */
273371
- mcVfsDlClose, /* xDlClose */
273372
- mcVfsRandomness, /* xRandomness */
273373
- mcVfsSleep, /* xSleep */
273374
- mcVfsCurrentTime, /* xCurrentTime */
273375
- mcVfsGetLastError, /* xGetLastError */
273376
- mcVfsCurrentTimeInt64, /* xCurrentTimeInt64 */
273377
- mcVfsSetSystemCall, /* xSetSystemCall */
273378
- mcVfsGetSystemCall, /* xGetSystemCall */
273379
- mcVfsNextSystemCall /* xNextSystemCall */
273380
- },
273381
- NULL
273382
- };
273383
-
273384
273541
  static sqlite3_io_methods mcIoMethodsGlobal =
273385
273542
  {
273386
273543
  3, /* iVersion */
@@ -273414,10 +273571,10 @@ static sqlite3_io_methods mcIoMethodsGlobal =
273414
273571
  static void mcMainListAdd(sqlite3mc_file* pFile)
273415
273572
  {
273416
273573
  assert( (pFile->openFlags & SQLITE_OPEN_MAIN_DB) );
273417
- sqlite3_mutex_enter(mcVfsGlobal.mutex);
273418
- pFile->pMainNext = mcVfsGlobal.pMain;
273419
- mcVfsGlobal.pMain = pFile;
273420
- sqlite3_mutex_leave(mcVfsGlobal.mutex);
273574
+ sqlite3_mutex_enter(pFile->pVfsMC->mutex);
273575
+ pFile->pMainNext = pFile->pVfsMC->pMain;
273576
+ pFile->pVfsMC->pMain = pFile;
273577
+ sqlite3_mutex_leave(pFile->pVfsMC->mutex);
273421
273578
  }
273422
273579
 
273423
273580
  /*
@@ -273426,11 +273583,11 @@ static void mcMainListAdd(sqlite3mc_file* pFile)
273426
273583
  static void mcMainListRemove(sqlite3mc_file* pFile)
273427
273584
  {
273428
273585
  sqlite3mc_file** pMainPrev;
273429
- sqlite3_mutex_enter(mcVfsGlobal.mutex);
273430
- for (pMainPrev = &mcVfsGlobal.pMain; *pMainPrev && *pMainPrev != pFile; pMainPrev = &((*pMainPrev)->pMainNext)){}
273586
+ sqlite3_mutex_enter(pFile->pVfsMC->mutex);
273587
+ for (pMainPrev = &pFile->pVfsMC->pMain; *pMainPrev && *pMainPrev != pFile; pMainPrev = &((*pMainPrev)->pMainNext)){}
273431
273588
  if (*pMainPrev) *pMainPrev = pFile->pMainNext;
273432
273589
  pFile->pMainNext = 0;
273433
- sqlite3_mutex_leave(mcVfsGlobal.mutex);
273590
+ sqlite3_mutex_leave(pFile->pVfsMC->mutex);
273434
273591
  }
273435
273592
 
273436
273593
  /*
@@ -273448,6 +273605,51 @@ static sqlite3mc_file* mcFindDbMainFileName(sqlite3mc_vfs* mcVfs, const char* zF
273448
273605
  return pDb;
273449
273606
  }
273450
273607
 
273608
+ /*
273609
+ ** Find a pointer to the Multiple Ciphers VFS in use for a database connection.
273610
+ */
273611
+ static sqlite3mc_vfs* mcFindVfs(sqlite3* db, const char* zDbName)
273612
+ {
273613
+ sqlite3mc_vfs* pVfsMC = NULL;
273614
+ if (db->pVfs && db->pVfs->xOpen == mcVfsOpen)
273615
+ {
273616
+ /* The top level VFS is a Multiple Ciphers VFS */
273617
+ pVfsMC = (sqlite3mc_vfs*)(db->pVfs);
273618
+ }
273619
+ else
273620
+ {
273621
+ /*
273622
+ ** The top level VFS is not a Multiple Ciphers VFS.
273623
+ ** Retrieve the VFS names stack.
273624
+ */
273625
+ char* zVfsNameStack = 0;
273626
+ if ((sqlite3_file_control(db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsNameStack) == SQLITE_OK) && (zVfsNameStack != NULL))
273627
+ {
273628
+ /* Search for the name prefix of a Multiple Ciphers VFS. */
273629
+ char* zVfsName = strstr(zVfsNameStack, SQLITE3MC_VFS_NAME);
273630
+ if (zVfsName != NULL)
273631
+ {
273632
+ /* The prefix was found, now determine the full VFS name. */
273633
+ char* zVfsNameEnd = zVfsName + strlen(SQLITE3MC_VFS_NAME);
273634
+ if (*zVfsNameEnd == '-')
273635
+ {
273636
+ for (++zVfsNameEnd; *zVfsNameEnd != '/' && *zVfsNameEnd != 0; ++zVfsNameEnd);
273637
+ if (*zVfsNameEnd == '/') *zVfsNameEnd = 0;
273638
+
273639
+ /* Find a pointer to the VFS with the determined name. */
273640
+ sqlite3_vfs* pVfs = sqlite3_vfs_find(zVfsName);
273641
+ if (pVfs && pVfs->xOpen == mcVfsOpen)
273642
+ {
273643
+ pVfsMC = (sqlite3mc_vfs*) pVfs;
273644
+ }
273645
+ }
273646
+ }
273647
+ sqlite3_free(zVfsNameStack);
273648
+ }
273649
+ }
273650
+ return pVfsMC;
273651
+ }
273652
+
273451
273653
  /*
273452
273654
  ** Find the codec of the database file
273453
273655
  ** corresponding to the database schema name.
@@ -273455,11 +273657,16 @@ static sqlite3mc_file* mcFindDbMainFileName(sqlite3mc_vfs* mcVfs, const char* zF
273455
273657
  SQLITE_PRIVATE Codec* sqlite3mcGetCodec(sqlite3* db, const char* zDbName)
273456
273658
  {
273457
273659
  Codec* codec = NULL;
273458
- const char* dbFileName = sqlite3_db_filename(db, zDbName);
273459
- sqlite3mc_file* pDbMain = mcFindDbMainFileName(&mcVfsGlobal, dbFileName);
273460
- if (pDbMain)
273660
+ sqlite3mc_vfs* pVfsMC = mcFindVfs(db, zDbName);
273661
+
273662
+ if (pVfsMC)
273461
273663
  {
273462
- codec = pDbMain->codec;
273664
+ const char* dbFileName = sqlite3_db_filename(db, zDbName);
273665
+ sqlite3mc_file* pDbMain = mcFindDbMainFileName(pVfsMC, dbFileName);
273666
+ if (pDbMain)
273667
+ {
273668
+ codec = pDbMain->codec;
273669
+ }
273463
273670
  }
273464
273671
  return codec;
273465
273672
  }
@@ -273482,9 +273689,14 @@ SQLITE_PRIVATE Codec* sqlite3mcGetMainCodec(sqlite3* db)
273482
273689
  ** connection handle is actually valid, because the association between
273483
273690
  ** connection handles and database file handles is not maintained properly.
273484
273691
  */
273485
- SQLITE_PRIVATE void sqlite3mcSetCodec(sqlite3* db, const char* zFileName, Codec* codec)
273692
+ SQLITE_PRIVATE void sqlite3mcSetCodec(sqlite3* db, const char* zDbName, const char* zFileName, Codec* codec)
273486
273693
  {
273487
- sqlite3mc_file* pDbMain = mcFindDbMainFileName(&mcVfsGlobal, zFileName);
273694
+ sqlite3mc_file* pDbMain = NULL;
273695
+ sqlite3mc_vfs* pVfsMC = mcFindVfs(db, zDbName);
273696
+ if (pVfsMC)
273697
+ {
273698
+ pDbMain = mcFindDbMainFileName((sqlite3mc_vfs*)(db->pVfs), zFileName);
273699
+ }
273488
273700
  if (pDbMain)
273489
273701
  {
273490
273702
  Codec* prevCodec = pDbMain->codec;
@@ -273553,6 +273765,7 @@ static int mcVfsOpen(sqlite3_vfs* pVfs, const char* zName, sqlite3_file* pFile,
273553
273765
  sqlite3mc_vfs* mcVfs = (sqlite3mc_vfs*) pVfs;
273554
273766
  sqlite3mc_file* mcFile = (sqlite3mc_file*) pFile;
273555
273767
  mcFile->pFile = (sqlite3_file*) &mcFile[1];
273768
+ mcFile->pVfsMC = mcVfs;
273556
273769
  mcFile->openFlags = flags;
273557
273770
  mcFile->zFileName = zName;
273558
273771
  mcFile->codec = 0;
@@ -273583,7 +273796,7 @@ static int mcVfsOpen(sqlite3_vfs* pVfs, const char* zName, sqlite3_file* pFile,
273583
273796
  else if (flags & SQLITE_OPEN_MAIN_JOURNAL)
273584
273797
  {
273585
273798
  const char* dbFileName = sqlite3_filename_database(zName);
273586
- mcFile->pMainDb = mcFindDbMainFileName(&mcVfsGlobal, dbFileName);
273799
+ mcFile->pMainDb = mcFindDbMainFileName(mcFile->pVfsMC, dbFileName);
273587
273800
  mcFile->zFileName = zName;
273588
273801
  SQLITE3MC_DEBUG_LOG("mcVfsOpen MAIN Journal: mcFile=%p fileName=%s dbFileName=%s\n", mcFile, mcFile->zFileName, dbFileName);
273589
273802
  }
@@ -273598,7 +273811,7 @@ static int mcVfsOpen(sqlite3_vfs* pVfs, const char* zName, sqlite3_file* pFile,
273598
273811
  else if (flags & SQLITE_OPEN_SUBJOURNAL)
273599
273812
  {
273600
273813
  const char* dbFileName = sqlite3_filename_database(zName);
273601
- mcFile->pMainDb = mcFindDbMainFileName(&mcVfsGlobal, dbFileName);
273814
+ mcFile->pMainDb = mcFindDbMainFileName(mcFile->pVfsMC, dbFileName);
273602
273815
  mcFile->zFileName = zName;
273603
273816
  SQLITE3MC_DEBUG_LOG("mcVfsOpen SUB Journal: mcFile=%p fileName=%s dbFileName=%s\n", mcFile, mcFile->zFileName, dbFileName);
273604
273817
  }
@@ -273614,7 +273827,7 @@ static int mcVfsOpen(sqlite3_vfs* pVfs, const char* zName, sqlite3_file* pFile,
273614
273827
  else if (flags & SQLITE_OPEN_WAL)
273615
273828
  {
273616
273829
  const char* dbFileName = sqlite3_filename_database(zName);
273617
- mcFile->pMainDb = mcFindDbMainFileName(&mcVfsGlobal, dbFileName);
273830
+ mcFile->pMainDb = mcFindDbMainFileName(mcFile->pVfsMC, dbFileName);
273618
273831
  mcFile->zFileName = zName;
273619
273832
  SQLITE3MC_DEBUG_LOG("mcVfsOpen WAL Journal: mcFile=%p fileName=%s dbFileName=%s\n", mcFile, mcFile->zFileName, dbFileName);
273620
273833
  }
@@ -273736,7 +273949,7 @@ static int mcIoClose(sqlite3_file* pFile)
273736
273949
  p->codec = 0;
273737
273950
  }
273738
273951
 
273739
- assert(p->pMainNext == 0 && mcVfsGlobal.pMain != p);
273952
+ assert(p->pMainNext == 0 && p->pVfsMC->pMain != p);
273740
273953
  rc = REALFILE(pFile)->pMethods->xClose(REALFILE(pFile));
273741
273954
  return rc;
273742
273955
  }
@@ -274398,6 +274611,14 @@ static int mcIoFileControl(sqlite3_file* pFile, int op, void* pArg)
274398
274611
  if (doReal)
274399
274612
  {
274400
274613
  rc = REALFILE(pFile)->pMethods->xFileControl(REALFILE(pFile), op, pArg);
274614
+ if (rc == SQLITE_OK && op == SQLITE_FCNTL_VFSNAME)
274615
+ {
274616
+ sqlite3mc_vfs* pVfsMC = p->pVfsMC;
274617
+ char* zIn = *(char**)pArg;
274618
+ char* zOut = sqlite3_mprintf("%s/%z", pVfsMC->base.zName, zIn);
274619
+ *(char**)pArg = zOut;
274620
+ if (zOut == 0) rc = SQLITE_NOMEM;
274621
+ }
274401
274622
  }
274402
274623
  return rc;
274403
274624
  }