-C Fix\sminor\sissues\son\sthis\sbranch.\sRemove\sunused\scode.
-D 2025-01-09T17:12:27.518
+C Rationalize\sand\sadd\scomments\sto\snew\scode\son\sthis\sbranch.
+D 2025-01-09T19:18:51.763
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2
F src/alter.c c48e7cbb7f87b28e9e954bfed3327d8e1b8e2a020fbb5bbeca78f6534d6c3c31
-F src/analyze.c 9dd9ad90bbdb40d19f267cfab450c1954998af093e790e644c92ea5f9c60b2f9
+F src/analyze.c bada576e160b40b138e2bcbcd41abaf29b4132ff71b01397e375de48203122b3
F src/attach.c 08235ab62ed5ccc93c22bf36e640d19effcd632319615851bccf724ec9341333
F src/auth.c 4c1ea890e0069ad73bead5d17a5b12c34cfa4f1a24175c8147ea439b64be271c
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
F src/btree.c 2664c81f217a42afadc7c010bb4a175057d5e53b99e9512234eb74817f2ad59c
F src/btree.h bdeeb35614caa33526b603138f04c8d07a3f90a1300b5ade76848b755edf2027
F src/btreeInt.h caa893e74d2261fb0ff1681fce998533c0552858e882bd04fc6805075f5f6e75
-F src/build.c 013ba4f080e4285eb9a53910f2ad5feb27cfa7163aeb51ebd30e49ee6a5242de
+F src/build.c 0bbe47ec72107ff9c7cee6039e504c685740ddf6db6f2e26cdafbc7a9ccf02e1
F src/callback.c 43c8ca52b1ecbdec43522f121126fd4e3ee10bc9ca01cdd3ae207cfa419780b6
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 193f6f9a75204274b7e7f45ac6d6517c12c70b55a5dfb39312dfc3a52e2a8138
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 05d90f8b28581f4ac3751a58e6d75ed18b29294381b3aa4c383c047ecdeabb82
-R 0c0c68967911f9b9f327790a38ea9222
+P c2610bb4becf5b5c58016947e07f5c7a330210370f0d2531ab9ecb1ce8658c1a
+R 3cce328d5df5fb5869ced3b1727dda7c
U dan
-Z 7fd56646f3baa04212ba296e6ca3b3bc
+Z 7b82e6f302472f161af8163c0726a6b1
# Remove this line to create a well-formed Fossil manifest.
** Schema.pStat4Space is only used when the aSample[] array is resized
** to exactly SQLITE_STAT4_EST_SAMPLES entries.
**
-**
+** If parameter nReq is non-zero, then it is the exact number of samples
+** to which the array should be sized. Or, if nReq is 0, then the array
+** is set to either SQLITE_STAT4_EST_SAMPLES (if pIdx->nSample==0), or
+** to pIdx->nSample*2 (if pIdx->nSample!=0).
*/
-static int growSampleArray(sqlite3 *db, Index *pIdx, int nReq, int *piOff){
+static int growSampleArray(sqlite3 *db, Index *pIdx, int nReq){
int nIdxCol = pIdx->nSampleCol;
int nNew = 0;
IndexSample *aNew = 0;
nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
if( nNew==SQLITE_STAT4_EST_SAMPLES ){
- aNew = (IndexSample*)&((u8*)pIdx->pSchema->pStat4Space)[*piOff];
- *piOff += nByte;
- assert( *piOff<=sqlite3_msize(pIdx->pSchema->pStat4Space) );
+ Schema *pSchema = pIdx->pSchema;
+ aNew = (IndexSample*)&((u8*)pSchema->pStat4Space)[pSchema->nStat4Space];
+ pSchema->nStat4Space += nByte;
+ assert( pSchema->nStat4Space<=sqlite3_msize(pSchema->pStat4Space) );
}else{
aNew = (IndexSample*)sqlite3DbMallocRaw(db, nByte);
if( aNew==0 ) return SQLITE_NOMEM_BKPT;
return SQLITE_OK;
}
+/*
+** Copy stat4 related data from index pFrom to index pTo. This is part
+** of the sqlite3_schema_copy() implementation. Return SQLITE_OK if
+** successful, or SQLITE_NOMEM if an OOM error is encountered.
+*/
int sqlite3AnalyzeCopyStat4(
- sqlite3 *db,
- Index *pTo,
- Index *pFrom
+ sqlite3 *db, /* Database handle */
+ Index *pTo, /* Target index (must belong to db) */
+ Index *pFrom /* Source index */
){
if( pFrom->nSample>0 ){
Schema *pSchema = pTo->pSchema;
int ii;
pTo->nSample = pTo->nSampleAlloc = 0;
- if( growSampleArray(db, pTo, pFrom->nSample, &pSchema->nStat4Space) ){
+ if( growSampleArray(db, pTo, pFrom->nSample) ){
return SQLITE_NOMEM;
}
pTo->nSample = pFrom->nSample;
if( nByte>0 ){
pSchema->pStat4Space = sqlite3_malloc(nByte);
+ pSchema->nStat4Space = 0;
if( pSchema->pStat4Space==0 ){
return SQLITE_NOMEM_BKPT;
}
- pSchema->nStat4Space = nByte;
}
return SQLITE_OK;
char *zSql; /* Text of the SQL statement */
Index *pPrevIdx = 0; /* Previous index in the loop */
IndexSample *pSample; /* A slot in pIdx->aSample[] */
- int iBlockOff = 0; /* Offset into Schema.pStat4Space */
assert( db->lookaside.bDisable );
pIdx->nSampleCol = pIdx->nColumn;
}
t2 = sqlite3STimeNow();
- if( growSampleArray(db, pIdx, 0, &iBlockOff) ) break;
+ if( growSampleArray(db, pIdx, 0) ) break;
if( db->aSchemaTime ){
db->aSchemaTime[SCHEMA_TIME_STAT4_GROWUS] += (sqlite3STimeNow() - t);
}
sqlite3WithDelete(db, (With*)pWith);
}
+/*
+** Type passed as context to expression walker callback schemaCopyExprCb().
+*/
struct TwoTable {
Table *pNew;
Table *pOld;
};
+/*
+** This is used as an expression walker callback. It takes a TwoTable
+** structure as context. Any TK_COLUMN node that points to TwoTable.pOld
+** is adjusted to point to TwoTable.pNew.
+*/
static int schemaCopyExprCb(Walker *p, Expr *pExpr){
struct TwoTable *pT = (struct TwoTable*)p->u.pSchema;
if( pExpr->op==TK_COLUMN && pExpr->y.pTab==pT->pOld ){
return WRC_Continue;
}
+/*
+** Set up the Walker passed as the first argument to call schemaCopyExprCb()
+** with the TwoTable object indicated by the second argument as context. This
+** configuration will modify all TK_COLUMN nodes that point to pT->pOld
+** to point to pT->pNew instead.
+*/
static void schemaCopyExprWalker(Walker *p, struct TwoTable *pT){
memset(p, 0, sizeof(*p));
p->xExprCallback = schemaCopyExprCb;
p->u.pSchema = (Schema*)pT;
}
-static Index *schemaCopyIndexList(sqlite3 *db, Table *pTab, Index *pIdx){
+/*
+** Argument pList points to a list of Index object linked by Index.pNext.
+** This function returns a copy of this list.
+**
+** All elements of the returned list have Index.pTable set to pTab, and
+** are set to be part of the same schema as pTab. Additionally, an entry
+** is inserted into pTab->pSchema->idxHash for each index in the returned
+** list.
+**
+** db->mallocFailed is left set if an OOM error is encountered.
+*/
+static Index *schemaCopyIndexList(sqlite3 *db, Table *pTab, Index *pList){
Schema *pSchema = pTab->pSchema;
Index *pRet = 0;
Index *p = 0;
Index **ppNew = &pRet;
- for(p=pIdx; p; p=p->pNext){
+ for(p=pList; p; p=p->pNext){
Index *pNew = 0;
int nName = sqlite3Strlen30(p->zName) + 1;
int nExtra = 0;
pNew->nSampleAlloc = 0;
sqlite3AnalyzeCopyStat4(db, pNew, p);
#endif
-
if( sqlite3HashInsert(&pSchema->idxHash, pNew->zName, pNew) ){
sqlite3OomFault(db);
}
return pRet;
}
+/*
+** Update any elements of pSrc with the fixedSchema flag set to use
+** schema pSchema.
+*/
static void schemaCopyRefixSrclist(Schema *pSchema, SrcList *pSrc){
if( pSrc ){
int ii;
}
}
+/*
+** Walker callback to call schemaCopyRefixSrclist().
+*/
static int schemaCopySelectCb(Walker *pWalker, Select *pSelect){
schemaCopyRefixSrclist(pWalker->u.pSchema, pSelect->pSrc);
return WRC_Continue;
}
+/*
+** Set up the walker object passed as the first argument so that it
+** calls schemaCopyRefixSrclist() on any SrcList it visits with pSchema
+** as the first argument.
+*/
+static void schemaRefixWalker(Walker *pWalker, Schema *pSchema){
+ memset(pWalker, 0, sizeof(Walker));
+ pWalker->xSelectCallback = schemaCopySelectCb;
+ pWalker->xExprCallback = sqlite3ExprWalkNoop;
+ pWalker->u.pSchema = pSchema;
+}
+
+/*
+** Make a copy of the list of trigger-steps in pList and return a pointer
+** to it. Set each trigger-step in the returned list to belong to trigger
+** pTrig, and also fix any embedded SrcList objects to schema pTrig->pSchema.
+**
+** db->mallocFailed is left set if an OOM error is encountered.
+*/
static TriggerStep *schemaCopyTriggerStepList(
- sqlite3 *db,
- Trigger *pTrig,
- TriggerStep *pList
+ sqlite3 *db, /* Database handle */
+ Trigger *pTrig, /* Trigger that will own returned list */
+ TriggerStep *pList /* List of trigger steps to copy */
){
TriggerStep *pRet = 0;
TriggerStep *p = 0;
return pRet;
}
+/*
+** Make a copy of the list of triggers in pList and return a pointer
+** to it. Set each of the triggers in the returned list to belong to table
+** pTab, and also fix any embedded SrcList objects to schema pTab->pSchema.
+**
+** An entry is added to hash table pTab->pSchema->trigHash for each trigger
+** in the returned list.
+**
+** db->mallocFailed is left set if an OOM error is encountered.
+*/
static Trigger *schemaCopyTriggerList(sqlite3 *db, Table *pTab, Trigger *pList){
Walker sWalker;
Schema *pSchema = pTab->pSchema;
Trigger *p = 0;
Trigger **ppNew = &pRet;
- memset(&sWalker, 0, sizeof(sWalker));
- sWalker.xSelectCallback = schemaCopySelectCb;
- sWalker.xExprCallback = sqlite3ExprWalkNoop;
- sWalker.u.pSchema = pSchema;
-
+ schemaRefixWalker(&sWalker, pSchema);
for(p=pList; p; p=p->pNext){
Trigger *pNew = sqlite3DbMallocZero(db, sizeof(Trigger));
if( pNew ){
return pRet;
}
+/*
+** Make a copy of the list of FKey objects in pList and return a pointer
+** to it. Set each of the FKey objects in the returned list to belong to
+** table pTab.
+**
+** An entry is added to hash table pTab->pSchema->fkeyHash for each trigger
+** in the returned list.
+**
+** db->mallocFailed is left set if an OOM error is encountered.
+*/
static FKey *schemaCopyFKeyList(sqlite3 *db, Table *pTab, FKey *pList){
Schema *pSchema = pTab->pSchema;
FKey *pRet = 0;
return pRet;
}
+/*
+** Make a copy of the table object passed as the 3rd argument. The copy
+** should be made part of schema pTo. The new table object is added to hash
+** table pTo->tblHash before returning.
+**
+** db->mallocFailed is left set if an OOM error is encountered.
+*/
static void schemaCopyTable(sqlite3 *db, Schema *pTo, Table *pTab){
Table *pNew = 0;
if( IsView(pNew) ){
Walker sWalker;
- memset(&sWalker, 0, sizeof(sWalker));
- sWalker.xSelectCallback = schemaCopySelectCb;
- sWalker.xExprCallback = sqlite3ExprWalkNoop;
- sWalker.u.pSchema = pTo;
pNew->u.view.pSelect = sqlite3SelectDup(db, pNew->u.view.pSelect, 0);
+ schemaRefixWalker(&sWalker, pTo);
sqlite3WalkSelect(&sWalker, pNew->u.view.pSelect);
}else if( IsVirtual(pNew) ){
int nAlloc = pNew->u.vtab.nArg * sizeof(char*);
}
}
+/*
+** Copy the contents of schema object pFrom to schema object pTo.
+**
+** db->mallocFailed is left set if an OOM error is encountered.
+*/
void sqlite3SchemaCopy(sqlite3 *db, Schema *pTo, Schema *pFrom){
HashElem *k = 0;
pTo->schemaFlags = pFrom->schemaFlags;
#ifdef SQLITE_ENABLE_STAT4
- if( pFrom->pStat4Space ){
+ if( pFrom->pStat4Space && pFrom->nStat4Space>0 ){
pTo->pStat4Space = sqlite3_malloc(pFrom->nStat4Space);
if( pTo->pStat4Space==0 ){
sqlite3OomFault(db);
EnableLookaside;
}
+/*
+** Copy the contents of the schema from database handle db, database zTo,
+** to database zFrom of handle dbFrom.
+**
+** Return SQLITE_OK if successful, or SQLITE_NOMEM if an OOM error is
+** encountered.
+*/
int sqlite3_schema_copy(
- sqlite3 *db, const char *zTo,
- sqlite3 *dbFrom, const char *zFrom
+ sqlite3 *db, const char *zTo, /* Target schema */
+ sqlite3 *dbFrom, const char *zFrom /* Source schema */
){
int iTo = 0;
int iFrom = 0;