mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Activate the one-pass optimization. Update comments, especially the
descriptions of the various objects. FossilOrigin-Name: e120c558a5bafc0f0d2cc12ee5c9d36e20cc642d
This commit is contained in:
12
manifest
12
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Bug\sfixes\sin\sthe\shandling\sof\svirtual\stables.
|
C Activate\sthe\sone-pass\soptimization.\s\sUpdate\scomments,\sespecially\sthe\ndescriptions\sof\sthe\svarious\sobjects.
|
||||||
D 2013-06-12T17:55:50.456
|
D 2013-06-12T20:18:16.225
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
|
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -289,7 +289,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83
|
|||||||
F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d
|
F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d
|
||||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||||
F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
|
F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
|
||||||
F src/where.c 568aef7548e2cad24f03b6099f07aa66b2fa269c
|
F src/where.c 4209851115ec883e004f0e0ec496215c9df10e33
|
||||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
||||||
@@ -1095,7 +1095,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
|||||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||||
F tool/wherecosttest.c 4d0393bdbe7230adb712e925863744dd2b7ffc5b
|
F tool/wherecosttest.c 4d0393bdbe7230adb712e925863744dd2b7ffc5b
|
||||||
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
||||||
P f2e15b1974e55373b5819e3b2326653f890f409f
|
P 25c0f7292a20c0db6ef176966d9987f29c7d73e5
|
||||||
R 6fa5c9c088caf080e0b4a5ec6cf7a456
|
R abdb63c5ef041b9c2f729e7a4c7abdae
|
||||||
U drh
|
U drh
|
||||||
Z 738850606e13a26064a82bd0faf55587
|
Z 9e2bd249132b4bdcba34d19dbfd465f2
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
25c0f7292a20c0db6ef176966d9987f29c7d73e5
|
e120c558a5bafc0f0d2cc12ee5c9d36e20cc642d
|
||||||
178
src/where.c
178
src/where.c
@@ -27,10 +27,10 @@
|
|||||||
#endif
|
#endif
|
||||||
#if defined(SQLITE_DEBUG) \
|
#if defined(SQLITE_DEBUG) \
|
||||||
&& (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
|
&& (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
|
||||||
# define WHERETRACE(X) if(sqlite3WhereTrace) sqlite3DebugPrintf X
|
# define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X
|
||||||
# define WHERETRACE_ENABLED 1
|
# define WHERETRACE_ENABLED 1
|
||||||
#else
|
#else
|
||||||
# define WHERETRACE(X)
|
# define WHERETRACE(K,X)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Forward reference
|
/* Forward reference
|
||||||
@@ -48,23 +48,32 @@ typedef struct WhereScan WhereScan;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Cost X is tracked as 10*log2(X) stored in a 16-bit integer. The
|
** Cost X is tracked as 10*log2(X) stored in a 16-bit integer. The
|
||||||
** maximum cost is 64*(2**63) which becomes 6900. So all costs can be
|
** maximum cost for ordinary tables is 64*(2**63) which becomes 6900.
|
||||||
** be stored in a 16-bit unsigned integer without risk of overflow.
|
** (Virtual tables can return a larger cost, but let's assume they do not.)
|
||||||
|
** So all costs can be stored in a 16-bit unsigned integer without risk
|
||||||
|
** of overflow.
|
||||||
|
**
|
||||||
|
** Costs are estimates, so don't go to the computational trouble to compute
|
||||||
|
** 10*log2(X) exactly. Instead, a close estimate is used. Any value of
|
||||||
|
** X<=1 is stored as 0. X=2 is 10. X=3 is 16. X=1000 is 99. etc.
|
||||||
|
**
|
||||||
*/
|
*/
|
||||||
typedef unsigned short int WhereCost;
|
typedef unsigned short int WhereCost;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** For each nested loop in a WHERE clause implementation, the WhereInfo
|
** This object contains information needed to implement a single nestd
|
||||||
** structure contains a single instance of this structure. This structure
|
** loop in WHERE clause.
|
||||||
** is intended to be private to the where.c module and should not be
|
|
||||||
** access or modified by other modules.
|
|
||||||
**
|
**
|
||||||
** The pIdxInfo field is used to help pick the best index on a
|
** Contrast this object with WhereLoop. This object describes the
|
||||||
** virtual table. The pIdxInfo pointer contains indexing
|
** implementation of the loop. WhereLoop describes the algorithm.
|
||||||
** information for the i-th table in the FROM clause before reordering.
|
** This object contains a pointer to the WhereLoop algorithm as one of
|
||||||
** All the pIdxInfo pointers are freed by whereInfoFree() in where.c.
|
** its elements.
|
||||||
** All other information in the i-th WhereLevel object for the i-th table
|
**
|
||||||
** after FROM clause ordering.
|
** The WhereInfo object contains a single instance of this object for
|
||||||
|
** each term in the FROM clause (which is to say, for each of the
|
||||||
|
** nested loops as implemented). The order of WhereLevel objects determines
|
||||||
|
** the loop nested order, with WhereInfo.a[0] being the outer loop and
|
||||||
|
** WhereInfo.a[WhereInfo.nLevel-1] being the inner loop.
|
||||||
*/
|
*/
|
||||||
struct WhereLevel {
|
struct WhereLevel {
|
||||||
int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */
|
int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */
|
||||||
@@ -92,10 +101,18 @@ struct WhereLevel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Each instance of this object represents a way of evaluating one
|
** Each instance of this object represents an algorithm for evaluating one
|
||||||
** term of a join. The WhereClause object holds a table of these
|
** term of a join. Every term of the FROM clause will have at least
|
||||||
** objects using (maskSelf,prereq,) as the primary key. Note that the
|
** one corresponding WhereLoop object (unless INDEXED BY constraints
|
||||||
** same join term might have multiple associated WhereLoop objects.
|
** prevent a query solution - which is an error) and many terms of the
|
||||||
|
** FROM clause will have multiple WhereLoop objects, each describing a
|
||||||
|
** potential way of implementing that FROM-clause term, together with
|
||||||
|
** dependencies and cost estimates for using the chosen algorithm.
|
||||||
|
**
|
||||||
|
** Query planning consists of building up a collection of these WhereLoop
|
||||||
|
** objects, then computing a particular sequence of WhereLoop objects, with
|
||||||
|
** one WhereLoop object per FROM clause term, that satisfy all dependencies
|
||||||
|
** and that minimize the overall cost.
|
||||||
*/
|
*/
|
||||||
struct WhereLoop {
|
struct WhereLoop {
|
||||||
Bitmask prereq; /* Bitmask of other loops that must run first */
|
Bitmask prereq; /* Bitmask of other loops that must run first */
|
||||||
@@ -136,7 +153,21 @@ static int whereLoopResize(sqlite3*, WhereLoop*, int);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Each instance of this object holds a sequence of WhereLoop objects
|
** Each instance of this object holds a sequence of WhereLoop objects
|
||||||
** that implement some or all of the entire query plan.
|
** that implement some or all of a query plan.
|
||||||
|
**
|
||||||
|
** Think of each WhereLoop objects as a node in a graph, which arcs
|
||||||
|
** showing dependences and costs for travelling between nodes. (That is
|
||||||
|
** not a completely accurate description because WhereLoop costs are a
|
||||||
|
** vector, not a scalar, and because dependences are many-to-one, not
|
||||||
|
** one-to-one as are graph nodes. But it is a useful visualization aid.)
|
||||||
|
** Then a WherePath object is a path through the graph that visits some
|
||||||
|
** or all of the WhereLoop objects once.
|
||||||
|
**
|
||||||
|
** The "solver" works by creating the N best WherePath objects of length
|
||||||
|
** 1. Then using those as a basis to compute the N best WherePath objects
|
||||||
|
** of length 2. And so forth until the length of WherePaths equals the
|
||||||
|
** number of nodes in the FROM clause. The best (lowest cost) WherePath
|
||||||
|
** at the end is the choosen query plan.
|
||||||
*/
|
*/
|
||||||
struct WherePath {
|
struct WherePath {
|
||||||
Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */
|
Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */
|
||||||
@@ -323,7 +354,8 @@ struct WhereMaskSet {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This object is a factory for WhereLoop objects for a particular query.
|
** This object is a convenience wrapper holding all information needed
|
||||||
|
** to construct WhereLoop objects for a particular query.
|
||||||
*/
|
*/
|
||||||
struct WhereLoopBuilder {
|
struct WhereLoopBuilder {
|
||||||
WhereInfo *pWInfo; /* Information about this WHERE */
|
WhereInfo *pWInfo; /* Information about this WHERE */
|
||||||
@@ -339,6 +371,9 @@ struct WhereLoopBuilder {
|
|||||||
** half does the tail of the WHERE loop. An instance of
|
** half does the tail of the WHERE loop. An instance of
|
||||||
** this structure is returned by the first half and passed
|
** this structure is returned by the first half and passed
|
||||||
** into the second half to give some continuity.
|
** into the second half to give some continuity.
|
||||||
|
**
|
||||||
|
** An instance of this object holds the complete state of the query
|
||||||
|
** planner.
|
||||||
*/
|
*/
|
||||||
struct WhereInfo {
|
struct WhereInfo {
|
||||||
Parse *pParse; /* Parsing and code generating context */
|
Parse *pParse; /* Parsing and code generating context */
|
||||||
@@ -364,9 +399,10 @@ struct WhereInfo {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Bitmasks for the operators that indices are able to exploit. An
|
** Bitmasks for the operators on WhereTerm objects. These are all
|
||||||
|
** operators that are of interest to the query planner. An
|
||||||
** OR-ed combination of these values can be used when searching for
|
** OR-ed combination of these values can be used when searching for
|
||||||
** terms in the where clause.
|
** particular WhereTerms within a WhereClause.
|
||||||
*/
|
*/
|
||||||
#define WO_IN 0x001
|
#define WO_IN 0x001
|
||||||
#define WO_EQ 0x002
|
#define WO_EQ 0x002
|
||||||
@@ -385,9 +421,9 @@ struct WhereInfo {
|
|||||||
#define WO_SINGLE 0x0ff /* Mask of all non-compound WO_* values */
|
#define WO_SINGLE 0x0ff /* Mask of all non-compound WO_* values */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Value for wsFlags returned by bestIndex() and stored in
|
** These are definitions of bits in the WhereLoop.wsFlags field.
|
||||||
** WhereLevel.wsFlags. These flags determine which search
|
** The particular combination of bits in each WhereLoop help to
|
||||||
** strategies are appropriate.
|
** determine the algorithm that WhereLoop represents.
|
||||||
*/
|
*/
|
||||||
#define WHERE_COLUMN_EQ 0x00000001 /* x=EXPR or x IN (...) or x IS NULL */
|
#define WHERE_COLUMN_EQ 0x00000001 /* x=EXPR or x IN (...) or x IS NULL */
|
||||||
#define WHERE_COLUMN_RANGE 0x00000002 /* x<EXPR and/or x>EXPR */
|
#define WHERE_COLUMN_RANGE 0x00000002 /* x<EXPR and/or x>EXPR */
|
||||||
@@ -409,6 +445,7 @@ struct WhereInfo {
|
|||||||
|
|
||||||
|
|
||||||
/* Convert a WhereCost value (10 times log2(X)) into its integer value X.
|
/* Convert a WhereCost value (10 times log2(X)) into its integer value X.
|
||||||
|
** A rough approximation is used. The value returned is not exact.
|
||||||
*/
|
*/
|
||||||
static u64 whereCostToInt(WhereCost x){
|
static u64 whereCostToInt(WhereCost x){
|
||||||
u64 n;
|
u64 n;
|
||||||
@@ -602,7 +639,7 @@ static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Initialize an expression mask set (a WhereMaskSet object)
|
** Initialize a WhereMaskSet object
|
||||||
*/
|
*/
|
||||||
#define initMaskSet(P) (P)->n=0
|
#define initMaskSet(P) (P)->n=0
|
||||||
|
|
||||||
@@ -635,18 +672,9 @@ static void createMask(WhereMaskSet *pMaskSet, int iCursor){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This routine walks (recursively) an expression tree and generates
|
** These routine walk (recursively) an expression tree and generates
|
||||||
** a bitmask indicating which tables are used in that expression
|
** a bitmask indicating which tables are used in that expression
|
||||||
** tree.
|
** tree.
|
||||||
**
|
|
||||||
** In order for this routine to work, the calling function must have
|
|
||||||
** previously invoked sqlite3ResolveExprNames() on the expression. See
|
|
||||||
** the header comment on that routine for additional information.
|
|
||||||
** The sqlite3ResolveExprNames() routines looks for column names and
|
|
||||||
** sets their opcodes to TK_COLUMN and their Expr.iTable fields to
|
|
||||||
** the VDBE cursor number of the table. This routine just has to
|
|
||||||
** translate the cursor numbers into bitmask values and OR all
|
|
||||||
** the bitmasks together.
|
|
||||||
*/
|
*/
|
||||||
static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*);
|
static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*);
|
||||||
static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*);
|
static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*);
|
||||||
@@ -700,7 +728,7 @@ static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){
|
|||||||
/*
|
/*
|
||||||
** Return TRUE if the given operator is one of the operators that is
|
** Return TRUE if the given operator is one of the operators that is
|
||||||
** allowed for an indexable WHERE clause term. The allowed operators are
|
** allowed for an indexable WHERE clause term. The allowed operators are
|
||||||
** "=", "<", ">", "<=", ">=", and "IN".
|
** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"
|
||||||
**
|
**
|
||||||
** IMPLEMENTATION-OF: R-59926-26393 To be usable by an index a term must be
|
** IMPLEMENTATION-OF: R-59926-26393 To be usable by an index a term must be
|
||||||
** of one of the following forms: column = expression column > expression
|
** of one of the following forms: column = expression column > expression
|
||||||
@@ -727,10 +755,9 @@ static int allowedOp(int op){
|
|||||||
** are converted into "Y op X".
|
** are converted into "Y op X".
|
||||||
**
|
**
|
||||||
** If left/right precedence rules come into play when determining the
|
** If left/right precedence rules come into play when determining the
|
||||||
** collating
|
** collating sequence, then COLLATE operators are adjusted to ensure
|
||||||
** side of the comparison, it remains associated with the same side after
|
** that the collating sequence does not change. For example:
|
||||||
** the commutation. So "Y collate NOCASE op X" becomes
|
** "Y collate NOCASE op X" becomes "X op Y" because any collation sequence on
|
||||||
** "X op Y". This is because any collation sequence on
|
|
||||||
** the left hand side of a comparison overrides any collation sequence
|
** the left hand side of a comparison overrides any collation sequence
|
||||||
** attached to the right. For the same reason the EP_Collate flag
|
** attached to the right. For the same reason the EP_Collate flag
|
||||||
** is not commuted.
|
** is not commuted.
|
||||||
@@ -871,6 +898,11 @@ WhereTerm *whereScanNext(WhereScan *pScan){
|
|||||||
** for terms of the form "X <op> <expr>" where X is column iColumn of table
|
** for terms of the form "X <op> <expr>" where X is column iColumn of table
|
||||||
** iCur. The <op> must be one of the operators described by opMask.
|
** iCur. The <op> must be one of the operators described by opMask.
|
||||||
**
|
**
|
||||||
|
** If the search is for X and the WHERE clause contains terms of the
|
||||||
|
** form X=Y then this routine might also return terms of the form
|
||||||
|
** "Y <op> <expr>". The number of levels of transitivity is limited,
|
||||||
|
** but is enough to handle most commonly occurring SQL statements.
|
||||||
|
**
|
||||||
** If X is not the INTEGER PRIMARY KEY then X must be compatible with
|
** If X is not the INTEGER PRIMARY KEY then X must be compatible with
|
||||||
** index pIdx.
|
** index pIdx.
|
||||||
*/
|
*/
|
||||||
@@ -959,8 +991,6 @@ static void exprAnalyze(SrcList*, WhereClause*, int);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Call exprAnalyze on all terms in a WHERE clause.
|
** Call exprAnalyze on all terms in a WHERE clause.
|
||||||
**
|
|
||||||
**
|
|
||||||
*/
|
*/
|
||||||
static void exprAnalyzeAll(
|
static void exprAnalyzeAll(
|
||||||
SrcList *pTabList, /* the FROM clause */
|
SrcList *pTabList, /* the FROM clause */
|
||||||
@@ -1739,11 +1769,8 @@ static void exprAnalyze(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This function searches the expression list passed as the second argument
|
** This function searches pList for a entry that matches the iCol-th column
|
||||||
** for an expression of type TK_COLUMN that refers to the same column and
|
** of index pIdx.
|
||||||
** uses the same collation sequence as the iCol'th column of index pIdx.
|
|
||||||
** Argument iBase is the cursor number used for the table that pIdx refers
|
|
||||||
** to.
|
|
||||||
**
|
**
|
||||||
** If such an expression is found, its index in pList->a[] is returned. If
|
** If such an expression is found, its index in pList->a[] is returned. If
|
||||||
** no expression is found, -1 is returned.
|
** no expression is found, -1 is returned.
|
||||||
@@ -1778,7 +1805,7 @@ static int findIndexCol(
|
|||||||
** Return true if the DISTINCT expression-list passed as the third argument
|
** Return true if the DISTINCT expression-list passed as the third argument
|
||||||
** is redundant.
|
** is redundant.
|
||||||
**
|
**
|
||||||
** A DISTINCT list is redundant if the database contains some set of
|
** A DISTINCT list is redundant if the database contains some subset of
|
||||||
** columns that are unique and non-null.
|
** columns that are unique and non-null.
|
||||||
*/
|
*/
|
||||||
static int isDistinctRedundant(
|
static int isDistinctRedundant(
|
||||||
@@ -1842,7 +1869,10 @@ static int isDistinctRedundant(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The sum of two WhereCosts
|
** The (an approximate) sum of two WhereCosts. This computation is
|
||||||
|
** not a simple "+" operator because WhereCost is stored as a logarithmic
|
||||||
|
** value.
|
||||||
|
**
|
||||||
*/
|
*/
|
||||||
static WhereCost whereCostAdd(WhereCost a, WhereCost b){
|
static WhereCost whereCostAdd(WhereCost a, WhereCost b){
|
||||||
static const unsigned char x[] = {
|
static const unsigned char x[] = {
|
||||||
@@ -1868,7 +1898,8 @@ static WhereCost whereCostAdd(WhereCost a, WhereCost b){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Convert an integer into a WhereCost
|
** Convert an integer into a WhereCost. In other words, compute a
|
||||||
|
** good approximatation for 10*log2(x).
|
||||||
*/
|
*/
|
||||||
static WhereCost whereCostFromInt(tRowcnt x){
|
static WhereCost whereCostFromInt(tRowcnt x){
|
||||||
static WhereCost a[] = { 0, 2, 3, 5, 6, 7, 8, 9 };
|
static WhereCost a[] = { 0, 2, 3, 5, 6, 7, 8, 9 };
|
||||||
@@ -1886,7 +1917,8 @@ static WhereCost whereCostFromInt(tRowcnt x){
|
|||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
/*
|
/*
|
||||||
** Convert a double (as received from xBestIndex of a virtual table)
|
** Convert a double (as received from xBestIndex of a virtual table)
|
||||||
** into a WhereCost
|
** into a WhereCost. In other words, compute an approximation for
|
||||||
|
** 10*log2(x).
|
||||||
*/
|
*/
|
||||||
static WhereCost whereCostFromDouble(double x){
|
static WhereCost whereCostFromDouble(double x){
|
||||||
u64 a;
|
u64 a;
|
||||||
@@ -1901,11 +1933,7 @@ static WhereCost whereCostFromDouble(double x){
|
|||||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Prepare a crude estimate of the logarithm of the input value.
|
** Estimate the logarithm of the input value to base 2.
|
||||||
** The results need not be exact. This is only used for estimating
|
|
||||||
** the total cost of performing operations with O(logN) or O(NlogN)
|
|
||||||
** complexity. Because N is just a guess, it is no great tragedy if
|
|
||||||
** logN is a little off.
|
|
||||||
*/
|
*/
|
||||||
static WhereCost estLog(WhereCost N){
|
static WhereCost estLog(WhereCost N){
|
||||||
WhereCost x = whereCostFromInt(N);
|
WhereCost x = whereCostFromInt(N);
|
||||||
@@ -2158,8 +2186,6 @@ static sqlite3_index_info *allocateIndexInfo(
|
|||||||
int nOrderBy;
|
int nOrderBy;
|
||||||
sqlite3_index_info *pIdxInfo;
|
sqlite3_index_info *pIdxInfo;
|
||||||
|
|
||||||
/*WHERETRACE(("Recomputing index info for %s...\n", pSrc->pTab->zName));*/
|
|
||||||
|
|
||||||
/* Count the number of possible WHERE clause constraints referring
|
/* Count the number of possible WHERE clause constraints referring
|
||||||
** to this virtual table */
|
** to this virtual table */
|
||||||
for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
|
for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
|
||||||
@@ -2250,8 +2276,8 @@ static sqlite3_index_info *allocateIndexInfo(
|
|||||||
/*
|
/*
|
||||||
** The table object reference passed as the second argument to this function
|
** The table object reference passed as the second argument to this function
|
||||||
** must represent a virtual table. This function invokes the xBestIndex()
|
** must represent a virtual table. This function invokes the xBestIndex()
|
||||||
** method of the virtual table with the sqlite3_index_info pointer passed
|
** method of the virtual table with the sqlite3_index_info object that
|
||||||
** as the argument.
|
** comes in as the 3rd argument to this function.
|
||||||
**
|
**
|
||||||
** If an error occurs, pParse is populated with an error message and a
|
** If an error occurs, pParse is populated with an error message and a
|
||||||
** non-zero value is returned. Otherwise, 0 is returned and the output
|
** non-zero value is returned. Otherwise, 0 is returned and the output
|
||||||
@@ -2266,7 +2292,6 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
|
|||||||
int i;
|
int i;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/*WHERETRACE(("xBestIndex for %s\n", pTab->zName));*/
|
|
||||||
TRACE_IDX_INPUTS(p);
|
TRACE_IDX_INPUTS(p);
|
||||||
rc = pVtab->pModule->xBestIndex(pVtab, p);
|
rc = pVtab->pModule->xBestIndex(pVtab, p);
|
||||||
TRACE_IDX_OUTPUTS(p);
|
TRACE_IDX_OUTPUTS(p);
|
||||||
@@ -2578,8 +2603,8 @@ static int whereRangeScanEst(
|
|||||||
iBase -= whereCostFromInt(iUpper - iLower);
|
iBase -= whereCostFromInt(iUpper - iLower);
|
||||||
}
|
}
|
||||||
*pRangeDiv = iBase;
|
*pRangeDiv = iBase;
|
||||||
/*WHERETRACE(("range scan regions: %u..%u div=%g\n",
|
WHERETRACE(0x100, ("range scan regions: %u..%u div=%d\n",
|
||||||
(u32)iLower, (u32)iUpper, *pRangeDiv));*/
|
(u32)iLower, (u32)iUpper, *pRangeDiv));
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2640,7 +2665,7 @@ static int whereEqualScanEst(
|
|||||||
if( pRhs==0 ) return SQLITE_NOTFOUND;
|
if( pRhs==0 ) return SQLITE_NOTFOUND;
|
||||||
rc = whereKeyStats(pParse, p, pRhs, 0, a);
|
rc = whereKeyStats(pParse, p, pRhs, 0, a);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
/*WHERETRACE(("equality scan regions: %d\n", (int)a[1]));*/
|
WHERETRACE(0x100,("equality scan regions: %d\n", (int)a[1]));
|
||||||
*pnRow = a[1];
|
*pnRow = a[1];
|
||||||
}
|
}
|
||||||
whereEqualScanEst_cancel:
|
whereEqualScanEst_cancel:
|
||||||
@@ -2686,7 +2711,7 @@ static int whereInScanEst(
|
|||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
|
if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
|
||||||
*pnRow = nRowEst;
|
*pnRow = nRowEst;
|
||||||
/*WHERETRACE(("IN row estimate: est=%g\n", nRowEst));*/
|
WHERETRACE(0x100,("IN row estimate: est=%g\n", nRowEst));
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -5060,9 +5085,7 @@ static int wherePathSolver(WhereInfo *pWInfo, WhereCost nRowEst){
|
|||||||
nLoop = pWInfo->nLevel;
|
nLoop = pWInfo->nLevel;
|
||||||
mxChoice = (nLoop==1) ? 1 : (nLoop==2 ? 5 : 10);
|
mxChoice = (nLoop==1) ? 1 : (nLoop==2 ? 5 : 10);
|
||||||
assert( nLoop<=pWInfo->pTabList->nSrc );
|
assert( nLoop<=pWInfo->pTabList->nSrc );
|
||||||
#ifdef WHERETRACE_ENABLED
|
WHERETRACE(0x002, ("---- begin solver\n"));
|
||||||
if( sqlite3WhereTrace>=2 ) sqlite3DebugPrintf("---- begin solver\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Allocate and initialize space for aTo and aFrom */
|
/* Allocate and initialize space for aTo and aFrom */
|
||||||
ii = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
|
ii = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
|
||||||
@@ -5088,11 +5111,7 @@ static int wherePathSolver(WhereInfo *pWInfo, WhereCost nRowEst){
|
|||||||
}else{
|
}else{
|
||||||
/* Compute an estimate on the cost to sort the entire result set */
|
/* Compute an estimate on the cost to sort the entire result set */
|
||||||
rSortCost = nRowEst + estLog(nRowEst);
|
rSortCost = nRowEst + estLog(nRowEst);
|
||||||
#ifdef WHERETRACE_ENABLED
|
WHERETRACE(0x002,("---- sort cost=%-3d\n", rSortCost));
|
||||||
if( sqlite3WhereTrace>=2 ){
|
|
||||||
sqlite3DebugPrintf("---- sort cost=%-3d\n", rSortCost);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute successively longer WherePaths using the previous generation
|
/* Compute successively longer WherePaths using the previous generation
|
||||||
@@ -5605,7 +5624,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Construct the WhereLoop objects */
|
/* Construct the WhereLoop objects */
|
||||||
WHERETRACE(("*** Optimizer Start ***\n"));
|
WHERETRACE(0xffff,("*** Optimizer Start ***\n"));
|
||||||
if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
|
if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
|
||||||
rc = whereLoopAddAll(&sWLB);
|
rc = whereLoopAddAll(&sWLB);
|
||||||
if( rc ) goto whereBeginError;
|
if( rc ) goto whereBeginError;
|
||||||
@@ -5664,21 +5683,20 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
WHERETRACE(("*** Optimizer Finished ***\n"));
|
WHERETRACE(0xffff,("*** Optimizer Finished ***\n"));
|
||||||
pWInfo->pParse->nQueryLoop += pWInfo->nRowOut;
|
pWInfo->pParse->nQueryLoop += pWInfo->nRowOut;
|
||||||
|
|
||||||
#if 0 /* FIXME: Add this back in? */
|
|
||||||
/* If the caller is an UPDATE or DELETE statement that is requesting
|
/* If the caller is an UPDATE or DELETE statement that is requesting
|
||||||
** to use a one-pass algorithm, determine if this is appropriate.
|
** to use a one-pass algorithm, determine if this is appropriate.
|
||||||
** The one-pass algorithm only works if the WHERE clause constraints
|
** The one-pass algorithm only works if the WHERE clause constraints
|
||||||
** the statement to update a single row.
|
** the statement to update a single row.
|
||||||
*/
|
*/
|
||||||
assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
|
assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
|
||||||
if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 && (andFlags & WHERE_ONEROW)!=0 ){
|
if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0
|
||||||
|
&& (pWInfo->a[0].pWLoop->wsFlags & WHERE_ONEROW)!=0 ){
|
||||||
pWInfo->okOnePass = 1;
|
pWInfo->okOnePass = 1;
|
||||||
pWInfo->a[0].plan.wsFlags &= ~WHERE_IDX_ONLY;
|
pWInfo->a[0].pWLoop->wsFlags &= ~WHERE_IDX_ONLY;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Open all tables in the pTabList and any indices selected for
|
/* Open all tables in the pTabList and any indices selected for
|
||||||
** searching those tables.
|
** searching those tables.
|
||||||
|
|||||||
Reference in New Issue
Block a user