-C Immediately\sreset\sall\spending\sprepared\sstatements\son\sany\scall\sto\nsqlite3_set_authorizer(),\seven\sif\sthe\sauthorizer\sis\sbeing\sdisabled.
-D 2026-02-09T19:58:04.336
+C Minor\stweaks\sto\sthe\sstar-query\soptimization\sin\sthe\squery\splanner.
+D 2026-02-10T18:28:41.694
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F src/wal.c 505a98fbc599a971d92cb90371cf54546c404cd61e04fd093e7b0c8ff978f9b6
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
-F src/where.c f1237550a01ccbc70141a523661173ddf802f48f7fe94feab9151a66f80c0d9d
+F src/where.c 7a7fe745dd8104d0276a3d3f6e6ac7f087af3dd9f34a90bc937e5e7aea817e15
F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da
F src/wherecode.c 783ecd30061c875c919a5163e4b55f9a0eccdaf7c9b17ad2908a1668a8766bc4
F src/whereexpr.c bb649ce81bd6dc0eabfa2533ff5656fc7a16411e520a6c59be43e73e51503cce
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 021e48e28931afd781e76db6293e60fd2ffb8377cb1051e8b802f2743a10fa5d
-R 8e691803f449515bcdce3d4bea85fe54
+P 5c0468acd1a12f7fd01b9974250fb42c5811939dc2319729a1ef93c073dc0071
+R a8a8cc651a9935d9d998addfdb1931ef
U drh
-Z d57a142f836bbfe387f4f44113a90926
+Z 9ecd247afb8d5321506fc416f50001e3
# Remove this line to create a well-formed Fossil manifest.
** 12 otherwise
**
** For the purposes of this heuristic, a star-query is defined as a query
-** with a large central table that is joined using an INNER JOIN,
-** not CROSS or OUTER JOINs, against four or more smaller tables.
-** The central table is called the "fact" table. The smaller tables
-** that get joined are "dimension tables". Also, any table that is
-** self-joined cannot be a dimension table; we assume that dimension
-** tables may only be joined against fact tables.
+** with a central "fact" table that is joined against multiple
+** "dimension" tables, subject to the following constraints:
+**
+** (aa) Only a five-way or larger join is considered for this
+** optimization. If there are fewer than four terms in the FROM
+** clause, this heuristic does not apply.
+**
+** (bb) The join between the fact table and the dimension tables must
+** be an INNER join. CROSS and OUTER JOINs do not qualify.
+**
+** (cc) A table must have 3 or more dimension tables in order to be
+** considered a fact table. (Was 4 prior to 2026-02-10.)
+**
+** (dd) A table that is a self-join cannot be a dimension table.
+** Dimension tables are joined against fact tables.
**
** SIDE EFFECT: (and really the whole point of this subroutine)
**
}
#endif /* SQLITE_DEBUG */
- if( nLoop>=5
+ if( nLoop>=4 /* Constraint (aa) */
&& !pWInfo->bStarDone
&& OptimizationEnabled(pWInfo->pParse->db, SQLITE_StarQuery)
){
pWInfo->bStarDone = 1; /* Only do this computation once */
- /* Look for fact tables with four or more dimensions where the
+ /* Look for fact tables with three or more dimensions where the
** dimension tables are not separately from the fact tables by an outer
** or cross join. Adjust cost weights if found.
*/
if( (pFactTab->fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){
/* If the candidate fact-table is the right table of an outer join
** restrict the search for dimension-tables to be tables to the right
- ** of the fact-table. */
- if( iFromIdx+4 > nLoop ) break; /* Impossible to reach nDep>=4 */
+ ** of the fact-table. Constraint (bb) */
+ if( iFromIdx+3 > nLoop ){
+ break; /* ^-- Impossible to reach nDep>=2 - Constraint (cc) */
+ }
while( pStart && pStart->iTab<=iFromIdx ){
pStart = pStart->pNextLoop;
}
}
for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){
if( (aFromTabs[pWLoop->iTab].fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){
- /* Fact-tables and dimension-tables cannot be separated by an
- ** outer join (at least for the definition of fact- and dimension-
- ** used by this heuristic). */
- break;
+ break; /* Constraint (bb) */
}
if( (pWLoop->prereq & m)!=0 /* pWInfo depends on iFromIdx */
&& (pWLoop->maskSelf & mSeen)==0 /* pWInfo not already a dependency */
}
}
}
- if( nDep<=3 ) continue;
+ if( nDep<=2 ){
+ continue; /* Constraint (cc) */
+ }
/* If we reach this point, it means that pFactTab is a fact table
** with four or more dimensions connected by inner joins. Proceed
pWLoop->rStarDelta = 0;
}
}
+#endif
+#ifdef WHERETRACE_ENABLED /* 0x80000 */
+ if( sqlite3WhereTrace & 0x80000 ){
+ Bitmask mShow = mSeen;
+ sqlite3DebugPrintf("Fact table %s(%d), dimensions:",
+ pFactTab->zAlias ? pFactTab->zAlias : pFactTab->pSTab->zName,
+ iFromIdx);
+ for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){
+ if( mShow & pWLoop->maskSelf ){
+ SrcItem *pDim = aFromTabs + pWLoop->iTab;
+ mShow &= ~pWLoop->maskSelf;
+ sqlite3DebugPrintf(" %s(%d)",
+ pDim->zAlias ? pDim->zAlias: pDim->pSTab->zName, pWLoop->iTab);
+ }
+ }
+ sqlite3DebugPrintf("\n");
+ }
#endif
pWInfo->bStarUsed = 1;
if( sqlite3WhereTrace & 0x80000 ){
SrcItem *pDim = aFromTabs + pWLoop->iTab;
sqlite3DebugPrintf(
- "Increase SCAN cost of dimension %s(%d) of fact %s(%d) to %d\n",
- pDim->zAlias ? pDim->zAlias: pDim->pSTab->zName, pWLoop->iTab,
- pFactTab->zAlias ? pFactTab->zAlias : pFactTab->pSTab->zName,
- iFromIdx, mxRun
+ "Increase SCAN cost of %s to %d\n",
+ pDim->zAlias ? pDim->zAlias: pDim->pSTab->zName, mxRun
);
}
pWLoop->rStarDelta = mxRun - pWLoop->rRun;