15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2001 September 15 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code. In place of 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing: 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you do good and not evil. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you find forgiveness for yourself and forgive others. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you share freely, never taking more than you give. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)************************************************************************* 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This module contains C code that generates VDBE code used to process 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the WHERE clause of SQL statements. This module is responsible for 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** generating the code that loops through a table looking for applicable 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** rows. Indices are selected and used to speed the search when doing 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** so is applicable. Because this module is responsible for selecting 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** indices, you might also think of this module as the "query optimizer". 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqliteInt.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Trace output macros 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3WhereTrace = 0; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define WHERETRACE(X) if(sqlite3WhereTrace) sqlite3DebugPrintf X 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define WHERETRACE(X) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Forward reference 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct WhereClause WhereClause; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct WhereMaskSet WhereMaskSet; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct WhereOrInfo WhereOrInfo; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct WhereAndInfo WhereAndInfo; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct WhereCost WhereCost; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The query generator uses an array of instances of this structure to 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** help it analyze the subexpressions of the WHERE clause. Each WHERE 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** clause subexpression is separated from the others by AND operators, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** usually, or sometimes subexpressions separated by OR. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** All WhereTerms are collected into a single WhereClause structure. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The following identity holds: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** WhereTerm.pWC->a[WhereTerm.idx] == WhereTerm 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** When a term is of the form: 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** X <op> <expr> 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** where X is a column name and <op> is one of certain operators, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** then WhereTerm.leftCursor and WhereTerm.u.leftColumn record the 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** cursor number and column number for X. WhereTerm.eOperator records 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the <op> using a bitmask encoding defined by WO_xxx below. The 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** use of a bitmask encoding for the operator allows us to search 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** quickly for terms that match any of several different operators. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A WhereTerm might also be two or more subterms connected by OR: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (t1.X <op> <expr>) OR (t1.Y <op> <expr>) OR .... 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** In this second case, wtFlag as the TERM_ORINFO set and eOperator==WO_OR 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and the WhereTerm.u.pOrInfo field points to auxiliary information that 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is collected about the 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If a term in the WHERE clause does not match either of the two previous 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** categories, then eOperator==0. The WhereTerm.pExpr field is still set 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to the original subexpression content and wtFlags is set up appropriately 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** but no other fields in the WhereTerm object are meaningful. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** When eOperator!=0, prereqRight and prereqAll record sets of cursor numbers, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** but they do so indirectly. A single WhereMaskSet structure translates 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** cursor number into bits and the translated bit is stored in the prereq 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** fields. The translation is used in order to maximize the number of 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** bits that will fit in a Bitmask. The VDBE cursor numbers might be 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** spread out over the non-negative integers. For example, the cursor 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** numbers might be 3, 8, 9, 10, 20, 23, 41, and 45. The WhereMaskSet 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** translates these sparse cursor numbers into consecutive integers 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** beginning with 0 in order to make the best possible use of the available 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** bits in the Bitmask. So, in the example above, the cursor numbers 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** would be mapped into integers 0 through 7. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The number of terms in a join is limited by the number of bits 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in prereqRight and prereqAll. The default is 64 bits, hence SQLite 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is only able to process joins with 64 or fewer tables. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct WhereTerm WhereTerm; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WhereTerm { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pExpr; /* Pointer to the subexpression that is this term */ 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iParent; /* Disable pWC->a[iParent] when this term disabled */ 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int leftCursor; /* Cursor number of X in "X <op> <expr>" */ 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int leftColumn; /* Column number of X in "X <op> <expr>" */ 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereOrInfo *pOrInfo; /* Extra information if eOperator==WO_OR */ 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereAndInfo *pAndInfo; /* Extra information if eOperator==WO_AND */ 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u16 eOperator; /* A WO_xx value describing <op> */ 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u8 wtFlags; /* TERM_xxx bit flags. See below */ 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u8 nChild; /* Number of children that must disable us */ 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC; /* The clause this term is part of */ 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */ 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */ 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Allowed values of WhereTerm.wtFlags 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TERM_DYNAMIC 0x01 /* Need to call sqlite3ExprDelete(db, pExpr) */ 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TERM_VIRTUAL 0x02 /* Added by the optimizer. Do not code */ 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TERM_CODED 0x04 /* This term is already coded */ 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TERM_COPIED 0x08 /* Has a child */ 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */ 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */ 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TERM_OR_OK 0x40 /* Used during OR-clause processing */ 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */ 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define TERM_VNULL 0x00 /* Disabled if not using stat2 */ 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** An instance of the following structure holds all information about a 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** WHERE clause. Mostly this is a container for one or more WhereTerms. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WhereClause { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse; /* The parser context */ 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */ 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask vmask; /* Bitmask identifying virtual table cursors */ 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u8 op; /* Split operator. TK_AND or TK_OR */ 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nTerm; /* Number of terms */ 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nSlot; /* Number of entries in a[] */ 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */ 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(SQLITE_SMALL_STACK) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm aStatic[1]; /* Initial static space for a[] */ 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm aStatic[8]; /* Initial static space for a[] */ 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A WhereTerm with eOperator==WO_OR has its u.pOrInfo pointer set to 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a dynamically allocated instance of the following structure. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WhereOrInfo { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause wc; /* Decomposition into subterms */ 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask indexable; /* Bitmask of all indexable tables in the clause */ 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A WhereTerm with eOperator==WO_AND has its u.pAndInfo pointer set to 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a dynamically allocated instance of the following structure. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WhereAndInfo { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause wc; /* The subexpression broken out */ 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** An instance of the following structure keeps track of a mapping 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** between VDBE cursor numbers and bits of the bitmasks in WhereTerm. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The VDBE cursor numbers are small integers contained in 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SrcList_item.iCursor and Expr.iTable fields. For any given WHERE 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** clause, the cursor numbers might not begin with 0 and they might 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** contain gaps in the numbering sequence. But we want to make maximum 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** use of the bits in our bitmasks. This structure provides a mapping 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** from the sparse cursor numbers into consecutive integers beginning 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** with 0. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If WhereMaskSet.ix[A]==B it means that The A-th bit of a Bitmask 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** corresponds VDBE cursor number B. The A-th bit of a bitmask is 1<<A. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** For example, if the WHERE clause expression used these VDBE 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** cursors: 4, 5, 8, 29, 57, 73. Then the WhereMaskSet structure 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** would map those cursor numbers into bits 0 through 5. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Note that the mapping is not necessarily ordered. In the example 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** above, the mapping might go like this: 4->3, 5->1, 8->2, 29->0, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 57->5, 73->4. Or one of 719 other combinations might be used. It 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** does not really matter. What is important is that sparse cursor 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** numbers all get mapped into bit numbers that begin with 0 and contain 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** no gaps. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WhereMaskSet { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int n; /* Number of assigned cursor values */ 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ix[BMS]; /* Cursor assigned to each bit */ 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A WhereCost object records a lookup strategy and the estimated 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** cost of pursuing that strategy. 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WhereCost { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WherePlan plan; /* The lookup strategy */ 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double rCost; /* Overall cost of pursuing this search strategy */ 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask used; /* Bitmask of cursors used by this plan */ 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Bitmasks for the operators that indices are able to exploit. An 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** OR-ed combination of these values can be used when searching for 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** terms in the where clause. 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WO_IN 0x001 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WO_EQ 0x002 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WO_LT (WO_EQ<<(TK_LT-TK_EQ)) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WO_LE (WO_EQ<<(TK_LE-TK_EQ)) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WO_GT (WO_EQ<<(TK_GT-TK_EQ)) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WO_GE (WO_EQ<<(TK_GE-TK_EQ)) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WO_MATCH 0x040 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WO_ISNULL 0x080 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WO_OR 0x100 /* Two or more OR-connected terms */ 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WO_AND 0x200 /* Two or more AND-connected terms */ 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WO_NOOP 0x800 /* This term does not restrict search space */ 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WO_ALL 0xfff /* Mask of all possible WO_* values */ 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WO_SINGLE 0x0ff /* Mask of all non-compound WO_* values */ 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Value for wsFlags returned by bestIndex() and stored in 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** WhereLevel.wsFlags. These flags determine which search 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** strategies are appropriate. 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The least significant 12 bits is reserved as a mask for WO_ values above. 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The WhereLevel.wsFlags field is usually set to WO_IN|WO_EQ|WO_ISNULL. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** But if the table is the right table of a left join, WhereLevel.wsFlags 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is set to WO_IN|WO_EQ. The WhereLevel.wsFlags field can then be used as 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the "op" parameter to findTerm when we are resolving equality constraints. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ISNULL constraints will then not be used on the right table of a left 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** join. Tickets #2177 and #2189. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_ROWID_EQ 0x00001000 /* rowid=EXPR or rowid IN (...) */ 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_ROWID_RANGE 0x00002000 /* rowid<EXPR and/or rowid>EXPR */ 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_COLUMN_EQ 0x00010000 /* x=EXPR or x IN (...) or x IS NULL */ 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_COLUMN_RANGE 0x00020000 /* x<EXPR and/or x>EXPR */ 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_COLUMN_IN 0x00040000 /* x IN (...) */ 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_COLUMN_NULL 0x00080000 /* x IS NULL */ 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */ 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_NOT_FULLSCAN 0x100f3000 /* Does not do a full table scan */ 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_IN_ABLE 0x000f1000 /* Able to support an IN operator */ 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */ 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */ 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_BOTH_LIMIT 0x00300000 /* Both x>EXPR and x<EXPR */ 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_IDX_ONLY 0x00800000 /* Use index only - omit table */ 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_ORDERBY 0x01000000 /* Output will appear in correct order */ 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_REVERSE 0x02000000 /* Scan in reverse order */ 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_UNIQUE 0x04000000 /* Selects no more than one row */ 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_VIRTUALTABLE 0x08000000 /* Use virtual-table processing */ 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_MULTI_OR 0x10000000 /* OR using multiple indices */ 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WHERE_TEMP_INDEX 0x20000000 /* Uses an ephemeral index */ 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Initialize a preallocated WhereClause structure. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void whereClauseInit( 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC, /* The WhereClause to be initialized */ 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* The parsing context */ 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereMaskSet *pMaskSet /* Mapping from table cursor numbers to bitmasks */ 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->pParse = pParse; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->pMaskSet = pMaskSet; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->nTerm = 0; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->nSlot = ArraySize(pWC->aStatic); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->a = pWC->aStatic; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->vmask = 0; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Forward reference */ 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void whereClauseClear(WhereClause*); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Deallocate all memory associated with a WhereOrInfo object. 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void whereOrInfoDelete(sqlite3 *db, WhereOrInfo *p){ 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereClauseClear(&p->wc); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(db, p); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Deallocate all memory associated with a WhereAndInfo object. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void whereAndInfoDelete(sqlite3 *db, WhereAndInfo *p){ 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereClauseClear(&p->wc); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(db, p); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Deallocate a WhereClause structure. The WhereClause structure 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** itself is not freed. This routine is the inverse of whereClauseInit(). 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void whereClauseClear(WhereClause *pWC){ 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *a; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db = pWC->pParse->db; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){ 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( a->wtFlags & TERM_DYNAMIC ){ 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprDelete(db, a->pExpr); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( a->wtFlags & TERM_ORINFO ){ 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereOrInfoDelete(db, a->u.pOrInfo); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( a->wtFlags & TERM_ANDINFO ){ 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereAndInfoDelete(db, a->u.pAndInfo); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pWC->a!=pWC->aStatic ){ 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(db, pWC->a); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Add a single new WhereTerm entry to the WhereClause object pWC. 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The new WhereTerm object is constructed from Expr p and with wtFlags. 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The index in pWC->a[] of the new WhereTerm is returned on success. 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 0 is returned if the new WhereTerm could not be added due to a memory 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** allocation error. The memory allocation failure will be recorded in 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the db->mallocFailed flag so that higher-level functions can detect it. 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine will increase the size of the pWC->a[] array as necessary. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the wtFlags argument includes TERM_DYNAMIC, then responsibility 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** for freeing the expression p is assumed by the WhereClause object pWC. 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This is true even if this routine fails to allocate a new WhereTerm. 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** WARNING: This routine might reallocate the space used to store 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** WhereTerms. All pointers to WhereTerms should be invalidated after 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** calling this routine. Such pointers may be reinitialized by referencing 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the pWC->a[] array. 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){ 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTerm; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idx; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( wtFlags & TERM_VIRTUAL ); /* EV: R-00211-15100 */ 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pWC->nTerm>=pWC->nSlot ){ 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pOld = pWC->a; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db = pWC->pParse->db; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 ); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pWC->a==0 ){ 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( wtFlags & TERM_DYNAMIC ){ 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprDelete(db, p); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->a = pOld; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOld!=pWC->aStatic ){ 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(db, pOld); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = &pWC->a[idx = pWC->nTerm++]; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->pExpr = p; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->wtFlags = wtFlags; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->pWC = pWC; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->iParent = -1; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return idx; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine identifies subexpressions in the WHERE clause where 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** each subexpression is separated by the AND operator or some other 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** operator specified in the op parameter. The WhereClause structure 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is filled with pointers to subexpressions. For example: 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** WHERE a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** \________/ \_______________/ \________________/ 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** slot[0] slot[1] slot[2] 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The original WHERE clause in pExpr is unaltered. All this routine 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** does is make slot[] entries point to substructure within pExpr. 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** In the previous sentence and in the diagram, "slot[]" refers to 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the WhereClause.a[] array. The slot[] array grows as needed to contain 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** all terms of the WHERE clause. 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){ 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->op = (u8)op; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pExpr==0 ) return; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pExpr->op!=op ){ 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereClauseInsert(pWC, pExpr, 0); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereSplit(pWC, pExpr->pLeft, op); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereSplit(pWC, pExpr->pRight, op); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Initialize an expression mask set (a WhereMaskSet object) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define initMaskSet(P) memset(P, 0, sizeof(*P)) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the bitmask for the given cursor number. Return 0 if 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** iCursor is not in the set. 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Bitmask getMask(WhereMaskSet *pMaskSet, int iCursor){ 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 ); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<pMaskSet->n; i++){ 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pMaskSet->ix[i]==iCursor ){ 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ((Bitmask)1)<<i; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Create a new mask for cursor iCursor. 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** There is one cursor per table in the FROM clause. The number of 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** tables in the FROM clause is limited by a test early in the 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3WhereBegin() routine. So we know that the pMaskSet->ix[] 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** array will never overflow. 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void createMask(WhereMaskSet *pMaskSet, int iCursor){ 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pMaskSet->n < ArraySize(pMaskSet->ix) ); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMaskSet->ix[pMaskSet->n++] = iCursor; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine walks (recursively) an expression tree and generates 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a bitmask indicating which tables are used in that expression 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** tree. 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** In order for this routine to work, the calling function must have 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** previously invoked sqlite3ResolveExprNames() on the expression. See 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the header comment on that routine for additional information. 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The sqlite3ResolveExprNames() routines looks for column names and 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sets their opcodes to TK_COLUMN and their Expr.iTable fields to 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the VDBE cursor number of the table. This routine just has to 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** translate the cursor numbers into bitmask values and OR all 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the bitmasks together. 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Bitmask exprTableUsage(WhereMaskSet *pMaskSet, Expr *p){ 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask mask = 0; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p==0 ) return 0; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->op==TK_COLUMN ){ 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask = getMask(pMaskSet, p->iTable); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mask; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask = exprTableUsage(pMaskSet, p->pRight); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask |= exprTableUsage(pMaskSet, p->pLeft); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ExprHasProperty(p, EP_xIsSelect) ){ 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask |= exprSelectTableUsage(pMaskSet, p->x.pSelect); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask |= exprListTableUsage(pMaskSet, p->x.pList); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mask; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Bitmask exprListTableUsage(WhereMaskSet *pMaskSet, ExprList *pList){ 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask mask = 0; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pList ){ 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<pList->nExpr; i++){ 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask |= exprTableUsage(pMaskSet, pList->a[i].pExpr); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mask; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){ 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask mask = 0; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( pS ){ 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask |= exprListTableUsage(pMaskSet, pS->pEList); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask |= exprListTableUsage(pMaskSet, pS->pGroupBy); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask |= exprListTableUsage(pMaskSet, pS->pOrderBy); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask |= exprTableUsage(pMaskSet, pS->pWhere); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask |= exprTableUsage(pMaskSet, pS->pHaving); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pS = pS->pPrior; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mask; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return TRUE if the given operator is one of the operators that is 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** allowed for an indexable WHERE clause term. The allowed operators are 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** "=", "<", ">", "<=", ">=", and "IN". 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** IMPLEMENTATION-OF: R-59926-26393 To be usable by an index a term must be 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of one of the following forms: column = expression column > expression 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** column >= expression column < expression column <= expression 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** expression = column expression > column expression >= column 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** expression < column expression <= column column IN 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (expression-list) column IN (subquery) column IS NULL 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int allowedOp(int op){ 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( TK_GT>TK_EQ && TK_GT<TK_GE ); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( TK_LT>TK_EQ && TK_LT<TK_GE ); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( TK_LE>TK_EQ && TK_LE<TK_GE ); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( TK_GE==TK_EQ+4 ); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Swap two objects of type TYPE. 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;} 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Commute a comparison operator. Expressions of the form "X op Y" 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** are converted into "Y op X". 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If a collation sequence is associated with either the left or right 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** side of the comparison, it remains associated with the same side after 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the commutation. So "Y collate NOCASE op X" becomes 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** "X collate NOCASE op Y". This is because any collation sequence on 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the left hand side of a comparison overrides any collation sequence 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** attached to the right. For the same reason the EP_ExpCollate flag 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is not commuted. 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void exprCommute(Parse *pParse, Expr *pExpr){ 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u16 expRight = (pExpr->pRight->flags & EP_ExpCollate); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN ); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pExpr->pRight->pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pExpr->pLeft->pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pExpr->pRight->flags = (pExpr->pRight->flags & ~EP_ExpCollate) | expLeft; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pExpr->pLeft->flags = (pExpr->pLeft->flags & ~EP_ExpCollate) | expRight; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SWAP(Expr*,pExpr->pRight,pExpr->pLeft); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pExpr->op>=TK_GT ){ 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( TK_LT==TK_GT+2 ); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( TK_GE==TK_LE+2 ); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( TK_GT>TK_EQ ); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( TK_GT<TK_LE ); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE ); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Translate from TK_xx operator to WO_xx bitmask. 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static u16 operatorMask(int op){ 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u16 c; 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( allowedOp(op) ); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( op==TK_IN ){ 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = WO_IN; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( op==TK_ISNULL ){ 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = WO_ISNULL; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = (u16)(WO_EQ<<(op-TK_EQ)); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( op!=TK_ISNULL || c==WO_ISNULL ); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( op!=TK_IN || c==WO_IN ); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( op!=TK_EQ || c==WO_EQ ); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( op!=TK_LT || c==WO_LT ); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( op!=TK_LE || c==WO_LE ); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( op!=TK_GT || c==WO_GT ); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( op!=TK_GE || c==WO_GE ); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return c; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Search for a term in the WHERE clause that is of the form "X <op> <expr>" 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** where X is a reference to the iColumn of table iCur and <op> is one of 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the WO_xx operator codes specified by the op parameter. 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return a pointer to the term. Return 0 if not found. 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static WhereTerm *findTerm( 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC, /* The WHERE clause to be searched */ 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iCur, /* Cursor number of LHS */ 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iColumn, /* Column number of LHS */ 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notReady, /* RHS must not overlap with this mask */ 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u32 op, /* Mask of WO_xx values describing operator */ 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *pIdx /* Must be compatible with this index, if not NULL */ 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTerm; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int k; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( iCur>=0 ); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) op &= WO_ALL; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){ 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->leftCursor==iCur 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (pTerm->prereqRight & notReady)==0 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && pTerm->u.leftColumn==iColumn 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (pTerm->eOperator & op)!=0 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pIdx && pTerm->eOperator!=WO_ISNULL ){ 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pX = pTerm->pExpr; 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CollSeq *pColl; 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char idxaff; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse = pWC->pParse; 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idxaff = pIdx->pTable->aCol[iColumn].affinity; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Figure out the collation sequence required from an index for 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** it to be useful for optimising expression pX. Store this 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** value in variable pColl. 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(pX->pLeft); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(pColl || pParse->nErr); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; pIdx->aiColumn[j]!=iColumn; j++){ 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( NEVER(j>=pIdx->nColumn) ) return 0; 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pTerm; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Forward reference */ 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void exprAnalyze(SrcList*, WhereClause*, int); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Call exprAnalyze on all terms in a WHERE clause. 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void exprAnalyzeAll( 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SrcList *pTabList, /* the FROM clause */ 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC /* the WHERE clause to be analyzed */ 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=pWC->nTerm-1; i>=0; i--){ 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exprAnalyze(pTabList, pWC, i); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Check to see if the given expression is a LIKE or GLOB operator that 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** can be optimized using inequality constraints. Return TRUE if it is 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** so and false if not. 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** In order for the operator to be optimizible, the RHS must be a string 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** literal that does not begin with a wildcard. 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int isLikeOrGlob( 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* Parsing and code generating context */ 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pExpr, /* Test this expression */ 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr **ppPrefix, /* Pointer to TK_STRING expression with pattern prefix */ 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *pisComplete, /* True if the only wildcard is % in the last character */ 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *pnoCase /* True if uppercase is equivalent to lowercase */ 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *z = 0; /* String on RHS of LIKE operator */ 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pRight, *pLeft; /* Right and left size of LIKE operator */ 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprList *pList; /* List of operands to the LIKE operator */ 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int c; /* One character in z[] */ 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cnt; /* Number of non-wildcard prefix characters */ 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char wc[3]; /* Wildcard characters */ 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db = pParse->db; /* Database connection */ 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_value *pVal = 0; 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int op; /* Opcode of pRight */ 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){ 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_EBCDIC 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *pnoCase ) return 0; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pList = pExpr->x.pList; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLeft = pList->a[1].pExpr; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLeft->op!=TK_COLUMN || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT ){ 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** be the name of an indexed column with TEXT affinity. */ 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */ 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pRight = pList->a[0].pExpr; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) op = pRight->op; 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( op==TK_REGISTER ){ 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) op = pRight->op2; 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( op==TK_VARIABLE ){ 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vdbe *pReprepare = pParse->pReprepare; 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iCol = pRight->iColumn; 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pVal = sqlite3VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){ 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z = (char *)sqlite3_value_text(pVal); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); /* IMP: R-23257-02778 */ 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( op==TK_STRING ){ 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z = pRight->u.zToken; 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( z ){ 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cnt = 0; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cnt++; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( cnt!=0 && 255!=(u8)z[cnt-1] ){ 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pPrefix; 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pisComplete = c==wc[0] && z[cnt+1]==0; 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pPrefix = sqlite3Expr(db, TK_STRING, z); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pPrefix ) pPrefix->u.zToken[cnt] = 0; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ppPrefix = pPrefix; 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( op==TK_VARIABLE ){ 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vdbe *v = pParse->pVdbe; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeSetVarmask(v, pRight->iColumn); /* IMP: R-23257-02778 */ 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *pisComplete && pRight->u.zToken[1] ){ 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the rhs of the LIKE expression is a variable, and the current 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** value of the variable means there is no need to invoke the LIKE 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** function, then no OP_Variable will be added to the program. 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** This causes problems for the sqlite3_bind_parameter_name() 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** API. To workaround them, add a dummy OP_Variable here. 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int r1 = sqlite3GetTempReg(pParse); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCodeTarget(pParse, pRight, r1); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeChangeP3(v, sqlite3VdbeCurrentAddr(v)-1, 0); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ReleaseTempReg(pParse, r1); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z = 0; 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ValueFree(pVal); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (z!=0); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Check to see if the given expression is of the form 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** column MATCH expr 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If it is then return TRUE. If not, return FALSE. 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int isMatchOfColumn( 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pExpr /* Test this expression */ 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprList *pList; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pExpr->op!=TK_FUNCTION ){ 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sqlite3StrICmp(pExpr->u.zToken,"match")!=0 ){ 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pList = pExpr->x.pList; 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pList->nExpr!=2 ){ 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pList->a[1].pExpr->op != TK_COLUMN ){ 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_VIRTUALTABLE */ 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the pBase expression originated in the ON or USING clause of 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a join, then transfer the appropriate markings over to derived. 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void transferJoinMarkings(Expr *pDerived, Expr *pBase){ 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pDerived->flags |= pBase->flags & EP_FromJoin; 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pDerived->iRightJoinTable = pBase->iRightJoinTable; 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Analyze a term that consists of two or more OR-connected 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** subterms. So in: 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ... WHERE (a=5) AND (b=7 OR c=9 OR d=13) AND (d=13) 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ^^^^^^^^^^^^^^^^^^^^ 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine analyzes terms such as the middle term in the above example. 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A WhereOrTerm object is computed and attached to the term under 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** analysis, regardless of the outcome of the analysis. Hence: 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** WhereTerm.wtFlags |= TERM_ORINFO 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** WhereTerm.u.pOrInfo = a dynamically allocated WhereOrTerm object 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The term being analyzed must have two or more of OR-connected subterms. 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A single subterm might be a set of AND-connected sub-subterms. 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Examples of terms under analysis: 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (A) t1.x=t2.y OR t1.x=t2.z OR t1.y=15 OR t1.z=t3.a+5 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (B) x=expr1 OR expr2=x OR x=expr3 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (C) t1.x=t2.y OR (t1.x=t2.z AND t1.y=15) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (D) x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*') 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (E) (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** CASE 1: 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If all subterms are of the form T.C=expr for some single column of C 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a single table T (as shown in example B above) then create a new virtual 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** term that is an equivalent IN expression. In other words, if the term 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** being analyzed is: 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** x = expr1 OR expr2 = x OR x = expr3 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** then create a new virtual term like this: 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** x IN (expr1,expr2,expr3) 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** CASE 2: 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If all subterms are indexable by a single table T, then set 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** WhereTerm.eOperator = WO_OR 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** WhereTerm.u.pOrInfo->indexable |= the cursor number for table T 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A subterm is "indexable" if it is of the form 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** "T.C <op> <expr>" where C is any column of table T and 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** <op> is one of "=", "<", "<=", ">", ">=", "IS NULL", or "IN". 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A subterm is also indexable if it is an AND of two or more 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** subsubterms at least one of which is indexable. Indexable AND 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** subterms have their eOperator set to WO_AND and they have 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** u.pAndInfo set to a dynamically allocated WhereAndTerm object. 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** From another point of view, "indexable" means that the subterm could 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** potentially be used with an index if an appropriate index exists. 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This analysis does not consider whether or not the index exists; that 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is something the bestIndex() routine will determine. This analysis 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** only looks at whether subterms appropriate for indexing exist. 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** All examples A through E above all satisfy case 2. But if a term 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** also statisfies case 1 (such as B) we know that the optimizer will 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** always prefer case 1, so in that case we pretend that case 2 is not 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** satisfied. 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** It might be the case that multiple tables are indexable. For example, 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (E) above is indexable on tables P, Q, and R. 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Terms that satisfy case 2 are candidates for lookup by using 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** separate indices to find rowids for each subterm and composing 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the union of all rowids using a RowSet object. This is similar 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to "bitmap indices" in other database engines. 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** OTHERWISE: 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If neither case 1 nor case 2 apply, then leave the eOperator set to 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** zero. This term is not useful for search. 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void exprAnalyzeOrTerm( 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SrcList *pSrc, /* the FROM clause */ 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC, /* the complete WHERE clause */ 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idxTerm /* Index of the OR-term to be analyzed */ 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse = pWC->pParse; /* Parser context */ 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db = pParse->db; /* Database connection */ 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTerm = &pWC->a[idxTerm]; /* The term to be analyzed */ 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pExpr = pTerm->pExpr; /* The expression of the term */ 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereMaskSet *pMaskSet = pWC->pMaskSet; /* Table use masks */ 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; /* Loop counters */ 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pOrWc; /* Breakup of pTerm into subterms */ 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pOrTerm; /* A Sub-term within the pOrWc */ 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereOrInfo *pOrInfo; /* Additional information associated with pTerm */ 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask chngToIN; /* Tables that might satisfy case 1 */ 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask indexable; /* Tables that are indexable, satisfying case 2 */ 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Break the OR clause into its separate subterms. The subterms are 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** stored in a WhereClause structure containing within the WhereOrInfo 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** object that is attached to the original OR clause term. 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( (pTerm->wtFlags & (TERM_DYNAMIC|TERM_ORINFO|TERM_ANDINFO))==0 ); 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pExpr->op==TK_OR ); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->u.pOrInfo = pOrInfo = sqlite3DbMallocZero(db, sizeof(*pOrInfo)); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOrInfo==0 ) return; 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->wtFlags |= TERM_ORINFO; 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrWc = &pOrInfo->wc; 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereClauseInit(pOrWc, pWC->pParse, pMaskSet); 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereSplit(pOrWc, pExpr, TK_OR); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exprAnalyzeAll(pSrc, pOrWc); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( db->mallocFailed ) return; 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pOrWc->nTerm>=2 ); 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Compute the set of tables that might satisfy cases 1 or 2. 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indexable = ~(Bitmask)0; 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chngToIN = ~(pWC->vmask); 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){ 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pOrTerm->eOperator & WO_SINGLE)==0 ){ 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereAndInfo *pAndInfo; 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pOrTerm->eOperator==0 ); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 ); 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chngToIN = 0; 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pAndInfo = sqlite3DbMallocRaw(db, sizeof(*pAndInfo)); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pAndInfo ){ 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pAndWC; 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pAndTerm; 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask b = 0; 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrTerm->u.pAndInfo = pAndInfo; 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrTerm->wtFlags |= TERM_ANDINFO; 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrTerm->eOperator = WO_AND; 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pAndWC = &pAndInfo->wc; 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereClauseInit(pAndWC, pWC->pParse, pMaskSet); 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereSplit(pAndWC, pOrTerm->pExpr, TK_AND); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exprAnalyzeAll(pSrc, pAndWC); 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( db->mallocFailed ); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !db->mallocFailed ){ 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){ 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pAndTerm->pExpr ); 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( allowedOp(pAndTerm->pExpr->op) ){ 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b |= getMask(pMaskSet, pAndTerm->leftCursor); 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indexable &= b; 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( pOrTerm->wtFlags & TERM_COPIED ){ 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Skip this term for now. We revisit it when we process the 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** corresponding TERM_VIRTUAL term */ 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask b; 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b = getMask(pMaskSet, pOrTerm->leftCursor); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOrTerm->wtFlags & TERM_VIRTUAL ){ 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent]; 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b |= getMask(pMaskSet, pOther->leftCursor); 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indexable &= b; 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOrTerm->eOperator!=WO_EQ ){ 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chngToIN = 0; 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chngToIN &= b; 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Record the set of tables that satisfy case 2. The set might be 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** empty. 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrInfo->indexable = indexable; 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->eOperator = indexable==0 ? 0 : WO_OR; 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** chngToIN holds a set of tables that *might* satisfy case 1. But 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** we have to do some additional checking to see if case 1 really 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is satisfied. 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** chngToIN will hold either 0, 1, or 2 bits. The 0-bit case means 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** that there is no possibility of transforming the OR clause into an 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** IN operator because one or more terms in the OR clause contain 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** something other than == on a column in the single table. The 1-bit 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** case means that every term of the OR clause is of the form 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** "table.column=expr" for some single table. The one bit that is set 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** will correspond to the common table. We still need to check to make 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** sure the same column is used on all terms. The 2-bit case is when 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the all terms are of the form "table1.column=table2.column". It 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** might be possible to form an IN operator with either table1.column 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** or table2.column as the LHS if either is common to every term of 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the OR clause. 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Note that terms of the form "table.column1=table.column2" (the 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** same table on both sizes of the ==) cannot be optimized. 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( chngToIN ){ 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int okToChngToIN = 0; /* True if the conversion to IN is valid */ 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iColumn = -1; /* Column index on lhs of IN operator */ 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iCursor = -1; /* Table cursor common to all terms */ 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j = 0; /* Loop counter */ 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Search for a table and column that appears on one side or the 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** other of the == operator in every subterm. That table and column 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** will be recorded in iCursor and iColumn. There might not be any 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** such table and column. Set okToChngToIN if an appropriate table 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** and column is found but leave okToChngToIN false if not found. 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<2 && !okToChngToIN; j++){ 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrTerm = pOrWc->a; 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){ 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pOrTerm->eOperator==WO_EQ ); 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrTerm->wtFlags &= ~TERM_OR_OK; 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOrTerm->leftCursor==iCursor ){ 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This is the 2-bit case and we are on the second iteration and 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** current term is from the first iteration. So skip this term. */ 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( j==1 ); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ){ 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This term must be of the form t1.a==t2.b where t2 is in the 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** chngToIN set but t1 is not. This term will be either preceeded 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** or follwed by an inverted copy (t2.b==t1.a). Skip this term 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** and use its inversion. */ 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pOrTerm->wtFlags & TERM_COPIED ); 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pOrTerm->wtFlags & TERM_VIRTUAL ); 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) ); 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iColumn = pOrTerm->u.leftColumn; 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iCursor = pOrTerm->leftCursor; 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<0 ){ 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* No candidate table+column was found. This can only occur 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** on the second iteration */ 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( j==1 ); 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( (chngToIN&(chngToIN-1))==0 ); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( chngToIN==getMask(pMaskSet, iCursor) ); 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( j==1 ); 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We have found a candidate table and column. Check to see if that 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** table and column is common to every term in the OR clause */ 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) okToChngToIN = 1; 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(; i>=0 && okToChngToIN; i--, pOrTerm++){ 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pOrTerm->eOperator==WO_EQ ); 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOrTerm->leftCursor!=iCursor ){ 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrTerm->wtFlags &= ~TERM_OR_OK; 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( pOrTerm->u.leftColumn!=iColumn ){ 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) okToChngToIN = 0; 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int affLeft, affRight; 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the right-hand side is also a column, then the affinities 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** of both right and left sides must be such that no type 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** conversions are required on the right. (Ticket #2249) 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) affRight = sqlite3ExprAffinity(pOrTerm->pExpr->pRight); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) affLeft = sqlite3ExprAffinity(pOrTerm->pExpr->pLeft); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( affRight!=0 && affRight!=affLeft ){ 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) okToChngToIN = 0; 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrTerm->wtFlags |= TERM_OR_OK; 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* At this point, okToChngToIN is true if original pTerm satisfies 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** case 1. In that case, construct a new virtual term that is 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** pTerm converted into an IN operator. 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** EV: R-00211-15100 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( okToChngToIN ){ 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pDup; /* A transient duplicate expression */ 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprList *pList = 0; /* The RHS of the IN operator */ 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pLeft = 0; /* The LHS of the IN operator */ 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pNew; /* The complete IN operator */ 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){ 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue; 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pOrTerm->eOperator==WO_EQ ); 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pOrTerm->leftCursor==iCursor ); 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pOrTerm->u.leftColumn==iColumn ); 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup); 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLeft = pOrTerm->pExpr->pLeft; 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pLeft!=0 ); 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pDup = sqlite3ExprDup(db, pLeft, 0); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0, 0); 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pNew ){ 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idxNew; 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transferJoinMarkings(pNew, pExpr); 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( !ExprHasProperty(pNew, EP_xIsSelect) ); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNew->x.pList = pList; 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( idxNew==0 ); 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exprAnalyze(pSrc, pWC, idxNew); 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = &pWC->a[idxTerm]; 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->a[idxNew].iParent = idxTerm; 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->nChild = 1; 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprListDelete(db, pList); 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->eOperator = WO_NOOP; /* case 1 trumps case 2 */ 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */ 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The input to this routine is an WhereTerm structure with only the 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** "pExpr" field filled in. The job of this routine is to analyze the 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** subexpression and populate all the other fields of the WhereTerm 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** structure. 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the expression is of the form "<expr> <op> X" it gets commuted 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to the standard form of "X <op> <expr>". 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the expression is of the form "X <op> Y" where both X and Y are 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** columns, then the original expression is unchanged and a new virtual 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** term of the form "Y <op> X" is added to the WHERE clause and 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** analyzed separately. The original term is marked with TERM_COPIED 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and the new term is marked with TERM_DYNAMIC (because it's pExpr 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** needs to be freed with the WhereClause) and TERM_VIRTUAL (because it 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is a commuted copy of a prior term.) The original term has nChild=1 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and the copy has idxParent set to the index of the original term. 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void exprAnalyze( 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SrcList *pSrc, /* the FROM clause */ 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC, /* the WHERE clause */ 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idxTerm /* Index of the term to be analyzed */ 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTerm; /* The term to be analyzed */ 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereMaskSet *pMaskSet; /* Set of table index masks */ 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pExpr; /* The expression to be analyzed */ 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask prereqLeft; /* Prerequesites of the pExpr->pLeft */ 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask prereqAll; /* Prerequesites of pExpr */ 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */ 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */ 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */ 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int noCase = 0; /* LIKE/GLOB distinguishes case */ 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int op; /* Top-level operator. pExpr->op */ 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse = pWC->pParse; /* Parsing context */ 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db = pParse->db; /* Database connection */ 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( db->mallocFailed ){ 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = &pWC->a[idxTerm]; 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMaskSet = pWC->pMaskSet; 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pExpr = pTerm->pExpr; 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft); 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) op = pExpr->op; 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( op==TK_IN ){ 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pExpr->pRight==0 ); 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ExprHasProperty(pExpr, EP_xIsSelect) ){ 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->prereqRight = exprSelectTableUsage(pMaskSet, pExpr->x.pSelect); 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->x.pList); 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( op==TK_ISNULL ){ 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->prereqRight = 0; 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight); 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prereqAll = exprTableUsage(pMaskSet, pExpr); 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ExprHasProperty(pExpr, EP_FromJoin) ){ 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask x = getMask(pMaskSet, pExpr->iRightJoinTable); 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prereqAll |= x; 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extraRight = x-1; /* ON clause terms may not be used with an index 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** on left table of a LEFT JOIN. Ticket #3015 */ 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->prereqAll = prereqAll; 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->leftCursor = -1; 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->iParent = -1; 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->eOperator = 0; 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){ 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pLeft = pExpr->pLeft; 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pRight = pExpr->pRight; 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLeft->op==TK_COLUMN ){ 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->leftCursor = pLeft->iTable; 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->u.leftColumn = pLeft->iColumn; 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->eOperator = operatorMask(op); 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pRight && pRight->op==TK_COLUMN ){ 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pNew; 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pDup; 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->leftCursor>=0 ){ 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idxNew; 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pDup = sqlite3ExprDup(db, pExpr, 0); 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( db->mallocFailed ){ 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprDelete(db, pDup); 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( idxNew==0 ) return; 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNew = &pWC->a[idxNew]; 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNew->iParent = idxTerm; 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = &pWC->a[idxTerm]; 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->nChild = 1; 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->wtFlags |= TERM_COPIED; 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pDup = pExpr; 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNew = pTerm; 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exprCommute(pParse, pDup); 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLeft = pDup->pLeft; 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNew->leftCursor = pLeft->iTable; 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNew->u.leftColumn = pLeft->iColumn; 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( (prereqLeft | extraRight) != prereqLeft ); 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNew->prereqRight = prereqLeft | extraRight; 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNew->prereqAll = prereqAll; 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNew->eOperator = operatorMask(pDup->op); 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_BETWEEN_OPTIMIZATION 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If a term is the BETWEEN operator, create two new virtual terms 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** that define the range that the BETWEEN implements. For example: 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** a BETWEEN b AND c 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is converted into: 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** (a BETWEEN b AND c) AND (a>=b) AND (a<=c) 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The two new terms are added onto the end of the WhereClause object. 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The new terms are "dynamic" and are children of the original BETWEEN 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** term. That means that if the BETWEEN term is coded, the children are 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** skipped. Or, if the children are satisfied by an index, the original 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** BETWEEN term is skipped. 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){ 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprList *pList = pExpr->x.pList; 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const u8 ops[] = {TK_GE, TK_LE}; 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pList!=0 ); 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pList->nExpr==2 ); 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<2; i++){ 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pNewExpr; 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idxNew; 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewExpr = sqlite3PExpr(pParse, ops[i], 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprDup(db, pExpr->pLeft, 0), 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0); 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( idxNew==0 ); 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exprAnalyze(pSrc, pWC, idxNew); 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = &pWC->a[idxTerm]; 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->a[idxNew].iParent = idxTerm; 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->nChild = 2; 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */ 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY) 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Analyze a term that is composed of two or more subterms connected by 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** an OR operator. 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if( pExpr->op==TK_OR ){ 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pWC->op==TK_AND ); 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exprAnalyzeOrTerm(pSrc, pWC, idxTerm); 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = &pWC->a[idxTerm]; 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_OR_OPTIMIZATION */ 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Add constraints to reduce the search space on a LIKE or GLOB 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** operator. 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** A like pattern of the form "x LIKE 'abc%'" is changed into constraints 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** x>='abc' AND x<'abd' AND x LIKE 'abc%' 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The last character of the prefix "abc" is incremented to form the 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** termination condition "abd". 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pWC->op==TK_AND 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase) 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pLeft; /* LHS of LIKE/GLOB operator */ 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pStr2; /* Copy of pStr1 - RHS of LIKE/GLOB operator */ 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pNewExpr1; 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pNewExpr2; 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idxNew1; 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idxNew2; 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CollSeq *pColl; /* Collating sequence to use */ 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLeft = pExpr->x.pList->a[1].pExpr; 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pStr2 = sqlite3ExprDup(db, pStr1, 0); 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !db->mallocFailed ){ 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u8 c, *pC; /* Last character before the first wildcard */ 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1]; 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = *pC; 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( noCase ){ 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The point is to increment the last character before the first 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** wildcard. But if we increment '@', that will push it into the 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** alphabetic range where case conversions will mess up the 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** inequality. To avoid this, make sure to also run the full 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** LIKE on all candidate expressions by clearing the isComplete flag 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c=='A'-1 ) isComplete = 0; /* EV: R-64339-08207 */ 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = sqlite3UpperToLower[c]; 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pC = c + 1; 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, noCase ? "NOCASE" : "BINARY",0); 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewExpr1 = sqlite3PExpr(pParse, TK_GE, 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl), 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pStr1, 0); 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC); 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( idxNew1==0 ); 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exprAnalyze(pSrc, pWC, idxNew1); 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewExpr2 = sqlite3PExpr(pParse, TK_LT, 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl), 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pStr2, 0); 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC); 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( idxNew2==0 ); 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exprAnalyze(pSrc, pWC, idxNew2); 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = &pWC->a[idxTerm]; 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( isComplete ){ 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->a[idxNew1].iParent = idxTerm; 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->a[idxNew2].iParent = idxTerm; 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->nChild = 2; 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Add a WO_MATCH auxiliary term to the constraint set if the 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** current expression is of the form: column MATCH expr. 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** This information is used by the xBestIndex methods of 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** virtual tables. The native query optimizer does not attempt 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** to do anything with MATCH functions. 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( isMatchOfColumn(pExpr) ){ 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idxNew; 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pRight, *pLeft; 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pNewTerm; 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask prereqColumn, prereqExpr; 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pRight = pExpr->x.pList->a[0].pExpr; 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLeft = pExpr->x.pList->a[1].pExpr; 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prereqExpr = exprTableUsage(pMaskSet, pRight); 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prereqColumn = exprTableUsage(pMaskSet, pLeft); 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (prereqExpr & prereqColumn)==0 ){ 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pNewExpr; 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewExpr = sqlite3PExpr(pParse, TK_MATCH, 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, sqlite3ExprDup(db, pRight, 0), 0); 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( idxNew==0 ); 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewTerm = &pWC->a[idxNew]; 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewTerm->prereqRight = prereqExpr; 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewTerm->leftCursor = pLeft->iTable; 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewTerm->u.leftColumn = pLeft->iColumn; 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewTerm->eOperator = WO_MATCH; 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewTerm->iParent = idxTerm; 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = &pWC->a[idxTerm]; 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->nChild = 1; 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->wtFlags |= TERM_COPIED; 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewTerm->prereqAll = pTerm->prereqAll; 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_VIRTUALTABLE */ 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* When sqlite_stat2 histogram data is available an operator of the 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** form "x IS NOT NULL" can sometimes be evaluated more efficiently 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** virtual term of that form. 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Note that the virtual term must be tagged with TERM_VNULL. This 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** TERM_VNULL tag will suppress the not-null check at the beginning 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** of the loop. Without the TERM_VNULL flag, the not-null check at 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the start of the loop will prevent any results from being returned. 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pExpr->op==TK_NOTNULL 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && pExpr->pLeft->op==TK_COLUMN 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && pExpr->pLeft->iColumn>=0 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pNewExpr; 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pLeft = pExpr->pLeft; 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idxNew; 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pNewTerm; 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewExpr = sqlite3PExpr(pParse, TK_GT, 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprDup(db, pLeft, 0), 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3PExpr(pParse, TK_NULL, 0, 0, 0), 0); 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idxNew = whereClauseInsert(pWC, pNewExpr, 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( idxNew ){ 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewTerm = &pWC->a[idxNew]; 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewTerm->prereqRight = 0; 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewTerm->leftCursor = pLeft->iTable; 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewTerm->u.leftColumn = pLeft->iColumn; 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewTerm->eOperator = WO_GT; 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewTerm->iParent = idxTerm; 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = &pWC->a[idxTerm]; 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->nChild = 1; 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->wtFlags |= TERM_COPIED; 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNewTerm->prereqAll = pTerm->prereqAll; 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_ENABLE_STAT2 */ 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Prevent ON clause terms of a LEFT JOIN from being used to drive 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** an index for tables to the left of the join. 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->prereqRight |= extraRight; 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return TRUE if any of the expressions in pList->a[iFirst...] contain 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a reference to any table other than the iBase table. 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int referencesOtherTables( 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprList *pList, /* Search expressions in ths list */ 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereMaskSet *pMaskSet, /* Mapping from tables to bitmaps */ 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iFirst, /* Be searching with the iFirst-th expression */ 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iBase /* Ignore references to this table */ 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask allowed = ~getMask(pMaskSet, iBase); 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( iFirst<pList->nExpr ){ 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (exprTableUsage(pMaskSet, pList->a[iFirst++].pExpr)&allowed)!=0 ){ 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine decides if pIdx can be used to satisfy the ORDER BY 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** clause. If it can, it returns 1. If pIdx cannot satisfy the 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ORDER BY clause, this routine returns 0. 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** pOrderBy is an ORDER BY clause from a SELECT statement. pTab is the 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** left-most table in the FROM clause of that same SELECT statement and 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the table has a cursor number of "base". pIdx is an index on pTab. 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** nEqCol is the number of columns of pIdx that are used as equality 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** constraints. Any of these columns may be missing from the ORDER BY 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** clause and the match can still be a success. 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** All terms of the ORDER BY that match against the index must be either 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ASC or DESC. (Terms of the ORDER BY clause past the end of a UNIQUE 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** index do not need to satisfy this constraint.) The *pbRev value is 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** set to 1 if the ORDER BY clause is all DESC and it is set to 0 if 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the ORDER BY clause is all ASC. 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int isSortingIndex( 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* Parsing context */ 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereMaskSet *pMaskSet, /* Mapping from table cursor numbers to bitmaps */ 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *pIdx, /* The index we are testing */ 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int base, /* Cursor number for the table to be sorted */ 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprList *pOrderBy, /* The ORDER BY clause */ 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nEqCol, /* Number of index columns with == constraints */ 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int wsFlags, /* Index usages flags */ 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *pbRev /* Set to 1 if ORDER BY is DESC */ 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j; /* Loop counters */ 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sortOrder = 0; /* XOR of index and ORDER BY sort direction */ 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nTerm; /* Number of ORDER BY terms */ 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ExprList_item *pTerm; /* A term of the ORDER BY clause */ 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db = pParse->db; 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pOrderBy!=0 ); 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nTerm = pOrderBy->nExpr; 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( nTerm>0 ); 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Argument pIdx must either point to a 'real' named index structure, 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** or an index structure allocated on the stack by bestBtreeIndex() to 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** represent the rowid index that is part of every table. */ 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pIdx->zName || (pIdx->nColumn==1 && pIdx->aiColumn[0]==-1) ); 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Match terms of the ORDER BY clause against columns of 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the index. 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Note that indices have pIdx->nColumn regular columns plus 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** one additional column containing the rowid. The rowid column 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** of the index is also allowed to match against the ORDER BY 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** clause. 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<=pIdx->nColumn; i++){ 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pExpr; /* The expression of the ORDER BY pTerm */ 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CollSeq *pColl; /* The collating sequence of pExpr */ 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int termSortOrder; /* Sort order for this term */ 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iColumn; /* The i-th column of the index. -1 for rowid */ 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iSortOrder; /* 1 for DESC, 0 for ASC on the i-th index term */ 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zColl; /* Name of the collating sequence for i-th index term */ 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pExpr = pTerm->pExpr; 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){ 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Can not use an index sort on anything that is not a column in the 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** left-most table of the FROM clause */ 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pColl = sqlite3ExprCollSeq(pParse, pExpr); 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !pColl ){ 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pColl = db->pDfltColl; 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pIdx->zName && i<pIdx->nColumn ){ 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iColumn = pIdx->aiColumn[i]; 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( iColumn==pIdx->pTable->iPKey ){ 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iColumn = -1; 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iSortOrder = pIdx->aSortOrder[i]; 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zColl = pIdx->azColl[i]; 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iColumn = -1; 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iSortOrder = 0; 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zColl = pColl->zName; 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pExpr->iColumn!=iColumn || sqlite3StrICmp(pColl->zName, zColl) ){ 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Term j of the ORDER BY clause does not match column i of the index */ 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i<nEqCol ){ 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If an index column that is constrained by == fails to match an 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** ORDER BY term, that is OK. Just ignore that column of the index 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( i==pIdx->nColumn ){ 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Index column i is the rowid. All other terms match. */ 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If an index column fails to match and is not constrained by == 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** then the index cannot satisfy the ORDER BY constraint. 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pIdx->aSortOrder!=0 || iColumn==-1 ); 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 ); 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( iSortOrder==0 || iSortOrder==1 ); 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) termSortOrder = iSortOrder ^ pTerm->sortOrder; 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i>nEqCol ){ 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( termSortOrder!=sortOrder ){ 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Indices can only be used if all ORDER BY terms past the 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** equality constraints are all either DESC or ASC. */ 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sortOrder = termSortOrder; 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j++; 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm++; 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( iColumn<0 && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){ 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the indexed column is the primary key and everything matches 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** so far and none of the ORDER BY terms to the right reference other 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** tables in the join, then we are assured that the index can be used 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** to sort because the primary key is unique and so none of the other 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** columns will make any difference 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = nTerm; 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pbRev = sortOrder!=0; 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j>=nTerm ){ 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* All terms of the ORDER BY clause are covered by this index so 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** this index can be used for sorting. */ 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pIdx->onError!=OE_None && i==pIdx->nColumn 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (wsFlags & WHERE_COLUMN_NULL)==0 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){ 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* All terms of this index match some prefix of the ORDER BY clause 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** and the index is UNIQUE and no terms on the tail of the ORDER BY 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** clause reference other tables in a join. If this is all true then 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the order by clause is superfluous. Not that if the matching 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** condition is IS NULL then the result is not necessarily unique 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** even on a UNIQUE index, so disallow those cases. */ 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Prepare a crude estimate of the logarithm of the input value. 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The results need not be exact. This is only used for estimating 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the total cost of performing operations with O(logN) or O(NlogN) 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** complexity. Because N is just a guess, it is no great tragedy if 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** logN is a little off. 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static double estLog(double N){ 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double logN = 1; 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double x = 10; 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( N>x ){ 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logN += 1; 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x *= 10; 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return logN; 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Two routines for printing the content of an sqlite3_index_info 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** structure. Used for testing and debugging only. If neither 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** are no-ops. 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_DEBUG) 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TRACE_IDX_INPUTS(sqlite3_index_info *p){ 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !sqlite3WhereTrace ) return; 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<p->nConstraint; i++){ 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DebugPrintf(" constraint[%d]: col=%d termid=%d op=%d usabled=%d\n", 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i, 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aConstraint[i].iColumn, 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aConstraint[i].iTermOffset, 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aConstraint[i].op, 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aConstraint[i].usable); 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<p->nOrderBy; i++){ 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DebugPrintf(" orderby[%d]: col=%d desc=%d\n", 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i, 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aOrderBy[i].iColumn, 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aOrderBy[i].desc); 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){ 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !sqlite3WhereTrace ) return; 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<p->nConstraint; i++){ 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i, 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aConstraintUsage[i].argvIndex, 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->aConstraintUsage[i].omit); 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DebugPrintf(" idxNum=%d\n", p->idxNum); 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr); 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed); 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost); 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_IDX_INPUTS(A) 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_IDX_OUTPUTS(A) 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Required because bestIndex() is called by bestOrClauseIndex() 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void bestIndex( 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse*, WhereClause*, struct SrcList_item*, 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask, Bitmask, ExprList*, WhereCost*); 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine attempts to find an scanning strategy that can be used 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to optimize an 'OR' expression that is part of a WHERE clause. 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The table associated with FROM clause term pSrc may be either a 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** regular B-Tree table or a virtual table. 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void bestOrClauseIndex( 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* The parsing context */ 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC, /* The WHERE clause */ 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SrcList_item *pSrc, /* The FROM clause term to search */ 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notReady, /* Mask of cursors not available for indexing */ 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notValid, /* Cursors not available for any purpose */ 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprList *pOrderBy, /* The ORDER BY clause */ 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereCost *pCost /* Lowest cost query plan */ 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_OR_OPTIMIZATION 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */ 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Bitmask maskSrc = getMask(pWC->pMaskSet, iCur); /* Bitmask for pSrc */ 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm]; /* End of pWC->a[] */ 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTerm; /* A single term of the WHERE clause */ 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* No OR-clause optimization allowed if the INDEXED BY or NOT INDEXED clauses 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** are used */ 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pSrc->notIndexed || pSrc->pIndex!=0 ){ 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Search the WHERE clause terms for a usable WO_OR term. */ 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->eOperator==WO_OR 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && ((pTerm->prereqAll & ~maskSrc) & notReady)==0 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (pTerm->u.pOrInfo->indexable & maskSrc)!=0 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc; 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm]; 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pOrTerm; 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags = WHERE_MULTI_OR; 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double rTotal = 0; 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double nRow = 0; 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask used = 0; 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){ 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereCost sTermCost; 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("... Multi-index OR testing for term %d of %d....\n", 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (pOrTerm - pOrWC->a), (pTerm - pWC->a) 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) )); 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOrTerm->eOperator==WO_AND ){ 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pAndWC = &pOrTerm->u.pAndInfo->wc; 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bestIndex(pParse, pAndWC, pSrc, notReady, notValid, 0, &sTermCost); 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( pOrTerm->leftCursor==iCur ){ 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause tempWC; 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempWC.pParse = pWC->pParse; 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempWC.pMaskSet = pWC->pMaskSet; 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempWC.op = TK_AND; 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempWC.a = pOrTerm; 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempWC.nTerm = 1; 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bestIndex(pParse, &tempWC, pSrc, notReady, notValid, 0, &sTermCost); 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rTotal += sTermCost.rCost; 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRow += sTermCost.plan.nRow; 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) used |= sTermCost.used; 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rTotal>=pCost->rCost ) break; 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If there is an ORDER BY clause, increase the scan cost to account 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** for the cost of the sort. */ 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOrderBy!=0 ){ 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("... sorting increases OR cost %.9g to %.9g\n", 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rTotal, rTotal+nRow*estLog(nRow))); 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rTotal += nRow*estLog(nRow); 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the cost of scanning using this OR term for optimization is 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** less than the current cost stored in pCost, replace the contents 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** of pCost. */ 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("... multi-index OR cost=%.9g nrow=%.9g\n", rTotal, nRow)); 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rTotal<pCost->rCost ){ 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->rCost = rTotal; 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->used = used; 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.nRow = nRow; 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.wsFlags = flags; 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.u.pTerm = pTerm; 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_OR_OPTIMIZATION */ 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_AUTOMATIC_INDEX 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return TRUE if the WHERE clause term pTerm is of a form where it 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** could be used with an index to access pSrc, assuming an appropriate 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** index existed. 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int termCanDriveIndex( 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTerm, /* WHERE clause term to check */ 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SrcList_item *pSrc, /* Table we are trying to access */ 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notReady /* Tables in outer loops of the join */ 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char aff; 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->leftCursor!=pSrc->iCursor ) return 0; 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->eOperator!=WO_EQ ) return 0; 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pTerm->prereqRight & notReady)!=0 ) return 0; 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity; 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_AUTOMATIC_INDEX 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the query plan for pSrc specified in pCost is a full table scan 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and indexing is allows (if there is no NOT INDEXED clause) and it 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** possible to construct a transient index that would perform better 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** than a full table scan even when the cost of constructing the index 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is taken into account, then alter the query plan to use the 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** transient index. 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void bestAutomaticIndex( 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* The parsing context */ 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC, /* The WHERE clause */ 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SrcList_item *pSrc, /* The FROM clause term to search */ 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notReady, /* Mask of cursors that are not available */ 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereCost *pCost /* Lowest cost query plan */ 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double nTableRow; /* Rows in the input table */ 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double logN; /* log(nTableRow) */ 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double costTempIdx; /* per-query cost of the transient index */ 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTerm; /* A single term of the WHERE clause */ 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pWCEnd; /* End of pWC->a[] */ 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Table *pTable; /* Table tht might be indexed */ 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pParse->db->flags & SQLITE_AutoIndex)==0 ){ 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Automatic indices are disabled at run-time */ 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){ 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We already have some kind of index in use for this query. */ 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pSrc->notIndexed ){ 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The NOT INDEXED clause appears in the SQL. */ 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pParse->nQueryLoop >= (double)1 ); 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTable = pSrc->pTab; 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nTableRow = pTable->nRowEst; 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logN = estLog(nTableRow); 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) costTempIdx = 2*logN*(nTableRow/pParse->nQueryLoop + 1); 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( costTempIdx>=pCost->rCost ){ 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The cost of creating the transient table would be greater than 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** doing the full table scan */ 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Search for any equality comparison term */ 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWCEnd = &pWC->a[pWC->nTerm]; 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( termCanDriveIndex(pTerm, pSrc, notReady) ){ 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("auto-index reduces cost from %.1f to %.1f\n", 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->rCost, costTempIdx)); 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->rCost = costTempIdx; 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.nRow = logN + 1; 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.wsFlags = WHERE_TEMP_INDEX; 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->used = pTerm->prereqRight; 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define bestAutomaticIndex(A,B,C,D,E) /* no-op */ 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_AUTOMATIC_INDEX 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate code to construct the Index object for an automatic index 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and to set up the WhereLevel object pLevel so that the code generator 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** makes use of the automatic index. 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void constructAutomaticIndex( 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* The parsing context */ 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC, /* The WHERE clause */ 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SrcList_item *pSrc, /* The FROM clause term to get the next index */ 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notReady, /* Mask of cursors that are not available */ 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereLevel *pLevel /* Write new index here */ 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nColumn; /* Number of columns in the constructed index */ 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTerm; /* A single term of the WHERE clause */ 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pWCEnd; /* End of pWC->a[] */ 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nByte; /* Byte of memory needed for pIdx */ 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *pIdx; /* Object describing the transient index */ 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vdbe *v; /* Prepared statement under construction */ 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int regIsInit; /* Register set by initialization */ 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int addrInit; /* Address of the initialization bypass jump */ 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Table *pTable; /* The table being indexed */ 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KeyInfo *pKeyinfo; /* Key information for the index */ 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int addrTop; /* Top of the index fill loop */ 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int regRecord; /* Register holding an index record */ 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int n; /* Column counter */ 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; /* Loop counter */ 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int mxBitCol; /* Maximum column in pSrc->colUsed */ 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CollSeq *pColl; /* Collating sequence to on a column */ 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask idxCols; /* Bitmap of columns used for indexing */ 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask extraCols; /* Bitmap of additional columns */ 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate code to skip over the creation and initialization of the 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** transient index on 2nd and subsequent iterations of the loop. */ 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = pParse->pVdbe; 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( v!=0 ); 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regIsInit = ++pParse->nMem; 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addrInit = sqlite3VdbeAddOp1(v, OP_If, regIsInit); 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Integer, 1, regIsInit); 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Count the number of columns that will be added to the index 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** and used to match WHERE clause constraints */ 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nColumn = 0; 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTable = pSrc->pTab; 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWCEnd = &pWC->a[pWC->nTerm]; 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idxCols = 0; 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( termCanDriveIndex(pTerm, pSrc, notReady) ){ 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iCol = pTerm->u.leftColumn; 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol; 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( iCol==BMS ); 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( iCol==BMS-1 ); 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (idxCols & cMask)==0 ){ 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nColumn++; 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idxCols |= cMask; 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( nColumn>0 ); 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->plan.nEq = nColumn; 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Count the number of additional columns needed to create a 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** covering index. A "covering index" is an index that contains all 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** columns that are needed by the query. With a covering index, the 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** original table never needs to be accessed. Automatic indices must 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** be a covering index because the index will not be updated if the 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** original table changes and the index and table cannot both be used 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** if they go out of sync. 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extraCols = pSrc->colUsed & (~idxCols | (((Bitmask)1)<<(BMS-1))); 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mxBitCol = (pTable->nCol >= BMS-1) ? BMS-1 : pTable->nCol; 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTable->nCol==BMS-1 ); 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTable->nCol==BMS-2 ); 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<mxBitCol; i++){ 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( extraCols & (((Bitmask)1)<<i) ) nColumn++; 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pSrc->colUsed & (((Bitmask)1)<<(BMS-1)) ){ 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nColumn += pTable->nCol - BMS + 1; 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->plan.wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WO_EQ; 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Construct the Index object to describe this index */ 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nByte = sizeof(Index); 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nByte += nColumn*sizeof(int); /* Index.aiColumn */ 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nByte += nColumn*sizeof(char*); /* Index.azColl */ 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nByte += nColumn; /* Index.aSortOrder */ 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx = sqlite3DbMallocZero(pParse->db, nByte); 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pIdx==0 ) return; 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->plan.u.pIdx = pIdx; 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx->azColl = (char**)&pIdx[1]; 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx->aiColumn = (int*)&pIdx->azColl[nColumn]; 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx->aSortOrder = (u8*)&pIdx->aiColumn[nColumn]; 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx->zName = "auto-index"; 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx->nColumn = nColumn; 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx->pTable = pTable; 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = 0; 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idxCols = 0; 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( termCanDriveIndex(pTerm, pSrc, notReady) ){ 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iCol = pTerm->u.leftColumn; 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol; 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (idxCols & cMask)==0 ){ 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pX = pTerm->pExpr; 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idxCols |= cMask; 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx->aiColumn[n] = pTerm->u.leftColumn; 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : "BINARY"; 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n++; 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( (u32)n==pLevel->plan.nEq ); 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Add additional columns needed to make the automatic index into 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** a covering index */ 19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<mxBitCol; i++){ 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( extraCols & (((Bitmask)1)<<i) ){ 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx->aiColumn[n] = i; 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx->azColl[n] = "BINARY"; 19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n++; 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pSrc->colUsed & (((Bitmask)1)<<(BMS-1)) ){ 19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=BMS-1; i<pTable->nCol; i++){ 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx->aiColumn[n] = i; 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx->azColl[n] = "BINARY"; 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n++; 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( n==nColumn ); 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Create the automatic index */ 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pKeyinfo = sqlite3IndexKeyinfo(pParse, pIdx); 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pLevel->iIdxCur>=0 ); 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp4(v, OP_OpenAutoindex, pLevel->iIdxCur, nColumn+1, 0, 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (char*)pKeyinfo, P4_KEYINFO_HANDOFF); 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VdbeComment((v, "for %s", pTable->zName)); 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Fill the automatic index with content */ 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regRecord = sqlite3GetTempReg(pParse); 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1); 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeJumpHere(v, addrTop); 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ReleaseTempReg(pParse, regRecord); 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Jump here when skipping the initialization */ 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeJumpHere(v, addrInit); 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Allocate and populate an sqlite3_index_info structure. It is the 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** responsibility of the caller to eventually release the structure 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** by passing the pointer returned by this function to sqlite3_free(). 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite3_index_info *allocateIndexInfo( 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC, 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SrcList_item *pSrc, 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprList *pOrderBy 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j; 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nTerm; 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sqlite3_index_constraint *pIdxCons; 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sqlite3_index_orderby *pIdxOrderBy; 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sqlite3_index_constraint_usage *pUsage; 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTerm; 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nOrderBy; 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_index_info *pIdxInfo; 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("Recomputing index info for %s...\n", pSrc->pTab->zName)); 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Count the number of possible WHERE clause constraints referring 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** to this virtual table */ 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->leftCursor != pSrc->iCursor ) continue; 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 ); 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTerm->eOperator==WO_IN ); 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTerm->eOperator==WO_ISNULL ); 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue; 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nTerm++; 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the ORDER BY clause contains only columns in the current 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** virtual table then allocate space for the aOrderBy part of 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the sqlite3_index_info structure. 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nOrderBy = 0; 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOrderBy ){ 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<pOrderBy->nExpr; i++){ 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pExpr = pOrderBy->a[i].pExpr; 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break; 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( i==pOrderBy->nExpr ){ 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nOrderBy = pOrderBy->nExpr; 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Allocate the sqlite3_index_info structure 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + sizeof(*pIdxOrderBy)*nOrderBy ); 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pIdxInfo==0 ){ 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ErrorMsg(pParse, "out of memory"); 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initialize the structure. The sqlite3_index_info structure contains 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** many fields that are declared "const" to prevent xBestIndex from 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** changing them. We have to do some funky casting in order to 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** initialize those fields. 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxCons = (struct sqlite3_index_constraint*)&pIdxInfo[1]; 20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(int*)&pIdxInfo->nConstraint = nTerm; 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(int*)&pIdxInfo->nOrderBy = nOrderBy; 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint = pIdxCons; 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy; 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage = 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pUsage; 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->leftCursor != pSrc->iCursor ) continue; 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 ); 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTerm->eOperator==WO_IN ); 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTerm->eOperator==WO_ISNULL ); 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue; 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxCons[j].iColumn = pTerm->u.leftColumn; 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxCons[j].iTermOffset = i; 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxCons[j].op = (u8)pTerm->eOperator; 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The direct assignment in the previous line is possible only because 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** following asserts verify this fact. */ 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH ); 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pTerm->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) ); 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j++; 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<nOrderBy; i++){ 20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pExpr = pOrderBy->a[i].pExpr; 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxOrderBy[i].iColumn = pExpr->iColumn; 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder; 20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pIdxInfo; 20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The table object reference passed as the second argument to this function 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** must represent a virtual table. This function invokes the xBestIndex() 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** method of the virtual table with the sqlite3_index_info pointer passed 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** as the argument. 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If an error occurs, pParse is populated with an error message and a 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** non-zero value is returned. Otherwise, 0 is returned and the output 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** part of the sqlite3_index_info structure is left populated. 20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Whether or not an error is returned, it is the responsibility of the 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** that this is required. 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("xBestIndex for %s\n", pTab->zName)); 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_IDX_INPUTS(p); 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pVtab->pModule->xBestIndex(pVtab, p); 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_IDX_OUTPUTS(p); 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=SQLITE_OK ){ 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_NOMEM ){ 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pParse->db->mallocFailed = 1; 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( !pVtab->zErrMsg ){ 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc)); 20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg); 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(pVtab->zErrMsg); 20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pVtab->zErrMsg = 0; 20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<p->nConstraint; i++){ 20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){ 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ErrorMsg(pParse, 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "table %s: xBestIndex returned an invalid plan", pTab->zName); 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pParse->nErr; 20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Compute the best index for a virtual table. 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The best index is computed by the xBestIndex method of the virtual 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** table module. This routine is really just a wrapper that sets up 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the sqlite3_index_info structure that is used to communicate with 21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** xBestIndex. 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** In a join, this routine might be called multiple times for the 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** same virtual table. The sqlite3_index_info structure is created 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and initialized on the first invocation and reused on all subsequent 21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** invocations. The sqlite3_index_info structure is also used when 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** code is generated to access the virtual table. The whereInfoDelete() 21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** routine takes care of freeing the sqlite3_index_info structure after 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** everybody has finished with it. 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void bestVirtualIndex( 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* The parsing context */ 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC, /* The WHERE clause */ 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SrcList_item *pSrc, /* The FROM clause term to search */ 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notReady, /* Mask of cursors not available for index */ 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notValid, /* Cursors not valid for any purpose */ 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprList *pOrderBy, /* The order by clause */ 21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereCost *pCost, /* Lowest cost query plan */ 21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_index_info **ppIdxInfo /* Index information passed to xBestIndex */ 21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Table *pTab = pSrc->pTab; 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_index_info *pIdxInfo; 21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sqlite3_index_constraint *pIdxCons; 21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sqlite3_index_constraint_usage *pUsage; 21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTerm; 21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j; 21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nOrderBy; 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double rCost; 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Make sure wsFlags is initialized to some sane value. Otherwise, if the 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** malloc in allocateIndexInfo() fails and this function returns leaving 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** wsFlags in an uninitialized state, the caller may behave unpredictably. 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(pCost, 0, sizeof(*pCost)); 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.wsFlags = WHERE_VIRTUALTABLE; 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the sqlite3_index_info structure has not been previously 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** allocated and initialized, then allocate and initialize it now. 21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxInfo = *ppIdxInfo; 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pIdxInfo==0 ){ 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ppIdxInfo = pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pOrderBy); 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pIdxInfo==0 ){ 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* At this point, the sqlite3_index_info structure that pIdxInfo points 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** to will have been initialized, either during the current invocation or 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** during some prior invocation. Now we just have to customize the 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** details of pIdxInfo for the current invocation and pass it to 21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** xBestIndex. 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The module name must be defined. Also, by this point there must 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** be a pointer to an sqlite3_vtab structure. Otherwise 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** sqlite3ViewGetColumnNames() would have picked up the error. 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pTab->azModuleArg && pTab->azModuleArg[0] ); 21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( sqlite3GetVTable(pParse->db, pTab) ); 21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Set the aConstraint[].usable fields and initialize all 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** output variables to zero. 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** aConstraint[].usable is true for constraints where the right-hand 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** side contains only references to tables to the left of the current 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** table. In other words, if the constraint is of the form: 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** column = expr 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** and we are evaluating a join, then the constraint on column is 21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** only valid if all tables referenced in expr occur to the left 21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** of the table containing column. 21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The aConstraints[] array contains entries for all constraints 21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** on the current table. That way we only have to compute it once 21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** even though we might try to pick the best index multiple times. 21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** For each attempt at picking an index, the order of tables in the 21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** join might be different so we have to recompute the usable flag 21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** each time. 21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; 21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pUsage = pIdxInfo->aConstraintUsage; 21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){ 21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = pIdxCons->iTermOffset; 21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = &pWC->a[j]; 21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxCons->usable = (pTerm->prereqRight¬Ready) ? 0 : 1; 21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); 21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pIdxInfo->needToFreeIdxStr ){ 21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(pIdxInfo->idxStr); 21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxInfo->idxStr = 0; 21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxInfo->idxNum = 0; 21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxInfo->needToFreeIdxStr = 0; 21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxInfo->orderByConsumed = 0; 22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */ 22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2); 22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nOrderBy = pIdxInfo->nOrderBy; 22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !pOrderBy ){ 22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxInfo->nOrderBy = 0; 22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( vtabBestIndex(pParse, pTab, pIdxInfo) ){ 22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; 22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<pIdxInfo->nConstraint; i++){ 22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pUsage[i].argvIndex>0 ){ 22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight; 22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If there is an ORDER BY clause, and the selected virtual table index 22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** does not satisfy it, increase the cost of the scan accordingly. This 22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** matches the processing for non-virtual tables in bestBtreeIndex(). 22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rCost = pIdxInfo->estimatedCost; 22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOrderBy && pIdxInfo->orderByConsumed==0 ){ 22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rCost += estLog(rCost)*rCost; 22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The cost is not allowed to be larger than SQLITE_BIG_DBL (the 22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** inital value of lowestCost in this loop. If it is, then the 22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** (cost<lowestCost) test below will never be true. 22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Use "(double)2" instead of "2.0" in case OMIT_FLOATING_POINT 22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is defined. 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (SQLITE_BIG_DBL/((double)2))<rCost ){ 22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->rCost = (SQLITE_BIG_DBL/((double)2)); 22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->rCost = rCost; 22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.u.pVtabIdx = pIdxInfo; 22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pIdxInfo->orderByConsumed ){ 22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.wsFlags |= WHERE_ORDERBY; 22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.nEq = 0; 22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxInfo->nOrderBy = nOrderBy; 22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Try to find a more efficient access pattern by using multiple indexes 22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** to optimize an OR expression within the WHERE clause. 22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost); 22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_VIRTUALTABLE */ 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Argument pIdx is a pointer to an index structure that has an array of 22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SQLITE_INDEX_SAMPLES evenly spaced samples of the first indexed column 22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** stored in Index.aSample. These samples divide the domain of values stored 22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the index into (SQLITE_INDEX_SAMPLES+1) regions. 22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Region 0 contains all values less than the first sample value. Region 22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 1 contains values between the first and second samples. Region 2 contains 22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** values between samples 2 and 3. And so on. Region SQLITE_INDEX_SAMPLES 22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** contains values larger than the last sample. 22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the index contains many duplicates of a single value, then it is 22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** possible that two or more adjacent samples can hold the same value. 22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** When that is the case, the smallest possible region code is returned 22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** when roundUp is false and the largest possible region code is returned 22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** when roundUp is true. 22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If successful, this function determines which of the regions value 22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** pVal lies in, sets *piRegion to the region index (a value between 0 22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and SQLITE_INDEX_SAMPLES+1, inclusive) and returns SQLITE_OK. 22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Or, if an OOM occurs while converting text values between encodings, 22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SQLITE_NOMEM is returned and *piRegion is undefined. 22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2 22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int whereRangeRegion( 22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* Database connection */ 22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *pIdx, /* Index to consider domain of */ 22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_value *pVal, /* Value to consider */ 22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int roundUp, /* Return largest valid region if true */ 22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *piRegion /* OUT: Region of domain in which value lies */ 22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( roundUp==0 || roundUp==1 ); 22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ALWAYS(pVal) ){ 22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IndexSample *aSample = pIdx->aSample; 22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i = 0; 22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int eType = sqlite3_value_type(pVal); 22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ 22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double r = sqlite3_value_double(pVal); 22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<SQLITE_INDEX_SAMPLES; i++){ 22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( aSample[i].eType==SQLITE_NULL ) continue; 22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( aSample[i].eType>=SQLITE_TEXT ) break; 22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( roundUp ){ 22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( aSample[i].u.r>r ) break; 22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( aSample[i].u.r>=r ) break; 22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( eType==SQLITE_NULL ){ 23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = 0; 23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( roundUp ){ 23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( i<SQLITE_INDEX_SAMPLES && aSample[i].eType==SQLITE_NULL ) i++; 23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db = pParse->db; 23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CollSeq *pColl; 23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const u8 *z; 23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int n; 23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* pVal comes from sqlite3ValueFromExpr() so the type cannot be NULL */ 23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); 23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( eType==SQLITE_BLOB ){ 23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z = (const u8 *)sqlite3_value_blob(pVal); 23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pColl = db->pDfltColl; 23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pColl->enc==SQLITE_UTF8 ); 23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pColl = sqlite3GetCollSeq(db, SQLITE_UTF8, 0, *pIdx->azColl); 23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pColl==0 ){ 23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ErrorMsg(pParse, "no such collation sequence: %s", 23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pIdx->azColl); 23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_ERROR; 23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z = (const u8 *)sqlite3ValueText(pVal, pColl->enc); 23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !z ){ 23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_NOMEM; 23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( z && pColl && pColl->xCmp ); 23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = sqlite3ValueBytes(pVal, pColl->enc); 23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<SQLITE_INDEX_SAMPLES; i++){ 23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int c; 23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int eSampletype = aSample[i].eType; 23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( eSampletype==SQLITE_NULL || eSampletype<eType ) continue; 23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (eSampletype!=eType) ) break; 23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_UTF16 23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pColl->enc!=SQLITE_UTF8 ){ 23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nSample; 23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zSample = sqlite3Utf8to16( 23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db, pColl->enc, aSample[i].u.z, aSample[i].nByte, &nSample 23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !zSample ){ 23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( db->mallocFailed ); 23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_NOMEM; 23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = pColl->xCmp(pColl->pUser, nSample, zSample, n, z); 23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(db, zSample); 23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else 23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z); 23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( c-roundUp>=0 ) break; 23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( i>=0 && i<=SQLITE_INDEX_SAMPLES ); 23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *piRegion = i; 23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* #ifdef SQLITE_ENABLE_STAT2 */ 23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If expression pExpr represents a literal value, set *pp to point to 23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** an sqlite3_value structure containing the same value, with affinity 23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** aff applied to it, before returning. It is the responsibility of the 23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** caller to eventually release this structure by passing it to 23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3ValueFree(). 23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the current parse is a recompile (sqlite3Reprepare()) and pExpr 23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is an SQL variable that currently has a non-NULL value bound to it, 23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** create an sqlite3_value structure containing this value, again with 23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** affinity aff applied to it, instead. 23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If neither of the above apply, set *pp to NULL. 23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If an error occurs, return an error code. Otherwise, SQLITE_OK. 23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2 23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int valueFromExpr( 23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, 23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pExpr, 23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u8 aff, 23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_value **pp 23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pExpr->op==TK_VARIABLE 23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) 23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iVar = pExpr->iColumn; 23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); /* IMP: R-23257-02778 */ 23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff); 23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp); 23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This function is used to estimate the number of rows that will be visited 24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** by scanning an index for a range of values. The range may have an upper 24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** bound, a lower bound, or both. The WHERE clause terms that set the upper 24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and lower bounds are represented by pLower and pUpper respectively. For 24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** example, assuming that index p is on t1(a): 24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ... FROM t1 WHERE a > ? AND a < ? ... 24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** |_____| |_____| 24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** | | 24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** pLower pUpper 24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If either of the upper or lower bound is not present, then NULL is passed in 24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** place of the corresponding WhereTerm. 24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The nEq parameter is passed the index of the index column subject to the 24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** range constraint. Or, equivalently, the number of equality constraints 24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** optimized by the proposed index scan. For example, assuming index p is 24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** on t1(a, b), and the SQL query is: 24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ... 24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** then nEq should be passed the value 1 (as the range restricted column, 24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** b, is the second left-most column of the index). Or, if the query is: 24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ... FROM t1 WHERE a > ? AND a < ? ... 24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** then nEq should be passed 0. 24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The returned value is an integer between 1 and 100, inclusive. A return 24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** value of 1 indicates that the proposed range scan is expected to visit 24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** approximately 1/100th (1%) of the rows selected by the nEq equality 24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** constraints (if any). A return value of 100 indicates that it is expected 24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** that the range scan will visit every row (100%) selected by the equality 24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** constraints. 24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** In the absence of sqlite_stat2 ANALYZE data, each range inequality 24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** reduces the search space by 3/4ths. Hence a single constraint (x>?) 24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** results in a return of 25 and a range constraint (x>? AND x<?) results 24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in a return of 6. 24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int whereRangeScanEst( 24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* Parsing & code generating context */ 24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *p, /* The index containing the range-compared column; "x" */ 24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nEq, /* index into p->aCol[] of the range-compared column */ 24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */ 24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ 24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *piEst /* OUT: Return value */ 24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_OK; 24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2 24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nEq==0 && p->aSample ){ 24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_value *pLowerVal = 0; 24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_value *pUpperVal = 0; 24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iEst; 24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iLower = 0; 24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iUpper = SQLITE_INDEX_SAMPLES; 24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int roundUpUpper = 0; 24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int roundUpLower = 0; 24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity; 24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLower ){ 24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pExpr = pLower->pExpr->pRight; 24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = valueFromExpr(pParse, pExpr, aff, &pLowerVal); 24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pLower->eOperator==WO_GT || pLower->eOperator==WO_GE ); 24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) roundUpLower = (pLower->eOperator==WO_GT) ?1:0; 24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK && pUpper ){ 24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pExpr = pUpper->pExpr->pRight; 24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = valueFromExpr(pParse, pExpr, aff, &pUpperVal); 24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pUpper->eOperator==WO_LT || pUpper->eOperator==WO_LE ); 24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) roundUpUpper = (pUpper->eOperator==WO_LE) ?1:0; 24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=SQLITE_OK || (pLowerVal==0 && pUpperVal==0) ){ 24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ValueFree(pLowerVal); 24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ValueFree(pUpperVal); 24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto range_est_fallback; 24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( pLowerVal==0 ){ 24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = whereRangeRegion(pParse, p, pUpperVal, roundUpUpper, &iUpper); 24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLower ) iLower = iUpper/2; 24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( pUpperVal==0 ){ 24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = whereRangeRegion(pParse, p, pLowerVal, roundUpLower, &iLower); 24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pUpper ) iUpper = (iLower + SQLITE_INDEX_SAMPLES + 1)/2; 24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = whereRangeRegion(pParse, p, pUpperVal, roundUpUpper, &iUpper); 24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = whereRangeRegion(pParse, p, pLowerVal, roundUpLower, &iLower); 24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("range scan regions: %d..%d\n", iLower, iUpper)); 24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iEst = iUpper - iLower; 24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( iEst==SQLITE_INDEX_SAMPLES ); 24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( iEst<=SQLITE_INDEX_SAMPLES ); 24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( iEst<1 ){ 24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *piEst = 50/SQLITE_INDEX_SAMPLES; 25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *piEst = (iEst*100)/SQLITE_INDEX_SAMPLES; 25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ValueFree(pLowerVal); 25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ValueFree(pUpperVal); 25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)range_est_fallback: 25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNUSED_PARAMETER(pParse); 25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNUSED_PARAMETER(p); 25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNUSED_PARAMETER(nEq); 25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pLower || pUpper ); 25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *piEst = 100; 25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *piEst /= 4; 25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pUpper ) *piEst /= 4; 25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2 25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Estimate the number of rows that will be returned based on 25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** an equality constraint x=VALUE and where that VALUE occurs in 25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the histogram data. This only works when x is the left-most 25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** column of an index and sqlite_stat2 histogram data is available 25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** for that index. When pExpr==NULL that means the constraint is 25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** "x IS NULL" instead of "x=VALUE". 25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write the estimated row count into *pnRow and return SQLITE_OK. 25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If unable to make an estimate, leave *pnRow unchanged and return 25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** non-zero. 25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine can fail if it is unable to load a collating sequence 25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** required for string comparison, or if unable to allocate memory 25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** for a UTF conversion required for comparison. The error is stored 25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in the pParse structure. 25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int whereEqualScanEst( 25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* Parsing & code generating context */ 25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *p, /* The index whose left-most column is pTerm */ 25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */ 25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double *pnRow /* Write the revised row estimate here */ 25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */ 25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iLower, iUpper; /* Range of histogram regions containing pRhs */ 25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u8 aff; /* Column affinity */ 25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; /* Subfunction return code */ 25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double nRowEst; /* New estimate of the number of rows */ 25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( p->aSample!=0 ); 25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aff = p->pTable->aCol[p->aiColumn[0]].affinity; 25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pExpr ){ 25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = valueFromExpr(pParse, pExpr, aff, &pRhs); 25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc ) goto whereEqualScanEst_cancel; 25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pRhs = sqlite3ValueNew(pParse->db); 25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pRhs==0 ) return SQLITE_NOTFOUND; 25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = whereRangeRegion(pParse, p, pRhs, 0, &iLower); 25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc ) goto whereEqualScanEst_cancel; 25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = whereRangeRegion(pParse, p, pRhs, 1, &iUpper); 25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc ) goto whereEqualScanEst_cancel; 25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("equality scan regions: %d..%d\n", iLower, iUpper)); 25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( iLower>=iUpper ){ 25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRowEst = p->aiRowEst[0]/(SQLITE_INDEX_SAMPLES*2); 25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nRowEst<*pnRow ) *pnRow = nRowEst; 25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRowEst = (iUpper-iLower)*p->aiRowEst[0]/SQLITE_INDEX_SAMPLES; 25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pnRow = nRowEst; 25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)whereEqualScanEst_cancel: 25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ValueFree(pRhs); 25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* defined(SQLITE_ENABLE_STAT2) */ 25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2 25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Estimate the number of rows that will be returned based on 25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** an IN constraint where the right-hand side of the IN operator 25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is a list of values. Example: 25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** WHERE x IN (1,2,3,4) 25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write the estimated row count into *pnRow and return SQLITE_OK. 25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If unable to make an estimate, leave *pnRow unchanged and return 25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** non-zero. 25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine can fail if it is unable to load a collating sequence 25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** required for string comparison, or if unable to allocate memory 25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** for a UTF conversion required for comparison. The error is stored 25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in the pParse structure. 25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int whereInScanEst( 25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* Parsing & code generating context */ 25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *p, /* The index whose left-most column is pTerm */ 25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ 25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double *pnRow /* Write the revised row estimate here */ 26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_value *pVal = 0; /* One value from list */ 26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iLower, iUpper; /* Range of histogram regions containing pRhs */ 26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u8 aff; /* Column affinity */ 26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_OK; /* Subfunction return code */ 26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double nRowEst; /* New estimate of the number of rows */ 26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nSpan = 0; /* Number of histogram regions spanned */ 26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nSingle = 0; /* Histogram regions hit by a single value */ 26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nNotFound = 0; /* Count of values that are not constants */ 26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; /* Loop counter */ 26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u8 aSpan[SQLITE_INDEX_SAMPLES+1]; /* Histogram regions that are spanned */ 26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u8 aSingle[SQLITE_INDEX_SAMPLES+1]; /* Histogram regions hit once */ 26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( p->aSample!=0 ); 26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aff = p->pTable->aCol[p->aiColumn[0]].affinity; 26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(aSpan, 0, sizeof(aSpan)); 26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(aSingle, 0, sizeof(aSingle)); 26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<pList->nExpr; i++){ 26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ValueFree(pVal); 26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = valueFromExpr(pParse, pList->a[i].pExpr, aff, &pVal); 26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc ) break; 26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){ 26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nNotFound++; 26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = whereRangeRegion(pParse, p, pVal, 0, &iLower); 26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc ) break; 26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = whereRangeRegion(pParse, p, pVal, 1, &iUpper); 26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc ) break; 26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( iLower>=iUpper ){ 26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aSingle[iLower] = 1; 26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( iLower>=0 && iUpper<=SQLITE_INDEX_SAMPLES ); 26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( iLower<iUpper ) aSpan[iLower++] = 1; 26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=nSpan=0; i<=SQLITE_INDEX_SAMPLES; i++){ 26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( aSpan[i] ){ 26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nSpan++; 26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( aSingle[i] ){ 26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nSingle++; 26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRowEst = (nSpan*2+nSingle)*p->aiRowEst[0]/(2*SQLITE_INDEX_SAMPLES) 26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + nNotFound*p->aiRowEst[1]; 26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0]; 26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pnRow = nRowEst; 26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("IN row estimate: nSpan=%d, nSingle=%d, nNotFound=%d, est=%g\n", 26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nSpan, nSingle, nNotFound, nRowEst)); 26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ValueFree(pVal); 26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* defined(SQLITE_ENABLE_STAT2) */ 26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Find the best query plan for accessing a particular table. Write the 26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** best query plan and its cost into the WhereCost object supplied as the 26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** last parameter. 26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The lowest cost plan wins. The cost is an estimate of the amount of 26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** CPU and disk I/O needed to process the requested result. 26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Factors that influence cost include: 26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** * The estimated number of rows that will be retrieved. (The 26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** fewer the better.) 26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** * Whether or not sorting must occur. 26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** * Whether or not there must be separate lookups in the 26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** index and in the main table. 26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If there was an INDEXED BY clause (pSrc->pIndex) attached to the table in 26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the SQL statement, then this function only considers plans using the 26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** named index. If no such plan is found, then the returned cost is 26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SQLITE_BIG_DBL. If a plan is found that uses the named index, 26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** then the cost is calculated in the usual way. 26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If a NOT INDEXED clause (pSrc->notIndexed!=0) was attached to the table 26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in the SELECT statement, then no indexes are considered. However, the 26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** selected plan may still take advantage of the built-in rowid primary key 26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** index. 26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void bestBtreeIndex( 26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* The parsing context */ 26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC, /* The WHERE clause */ 26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SrcList_item *pSrc, /* The FROM clause term to search */ 26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notReady, /* Mask of cursors not available for indexing */ 26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notValid, /* Cursors not available for any purpose */ 26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprList *pOrderBy, /* The ORDER BY clause */ 26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereCost *pCost /* Lowest cost query plan */ 26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */ 26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *pProbe; /* An index we are evaluating */ 26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *pIdx; /* Copy of pProbe, or zero for IPK index */ 26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int eqTermMask; /* Current mask of valid equality operators */ 26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idxEqTermMask; /* Index mask of valid equality operators */ 26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index sPk; /* A fake index object for the primary key */ 27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */ 27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int aiColumnPk = -1; /* The aColumn[] value for the sPk index */ 27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int wsFlagMask; /* Allowed flags in pCost->plan.wsFlag */ 27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initialize the cost to a worst-case value */ 27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(pCost, 0, sizeof(*pCost)); 27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->rCost = SQLITE_BIG_DBL; 27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the pSrc table is the right table of a LEFT JOIN then we may not 27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** use an index to satisfy IS NULL constraints on that table. This is 27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** because columns might end up being NULL if the table does not match - 27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** a circumstance which the index cannot help us discover. Ticket #2177. 27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pSrc->jointype & JT_LEFT ){ 27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idxEqTermMask = WO_EQ|WO_IN; 27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idxEqTermMask = WO_EQ|WO_IN|WO_ISNULL; 27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pSrc->pIndex ){ 27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* An INDEXED BY clause specifies a particular index to use */ 27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx = pProbe = pSrc->pIndex; 27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE); 27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eqTermMask = idxEqTermMask; 27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* There is no INDEXED BY clause. Create a fake Index object in local 27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** variable sPk to represent the rowid primary key index. Make this 27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** fake index the first in a chain of Index objects with all of the real 27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** indices to follow */ 27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *pFirst; /* First of real indices on the table */ 27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&sPk, 0, sizeof(Index)); 27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sPk.nColumn = 1; 27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sPk.aiColumn = &aiColumnPk; 27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sPk.aiRowEst = aiRowEstPk; 27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sPk.onError = OE_Replace; 27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sPk.pTable = pSrc->pTab; 27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aiRowEstPk[0] = pSrc->pTab->nRowEst; 27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aiRowEstPk[1] = 1; 27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pFirst = pSrc->pTab->pIndex; 27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pSrc->notIndexed==0 ){ 27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The real indices of the table are only considered if the 27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** NOT INDEXED qualifier is omitted from the FROM clause */ 27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sPk.pNext = pFirst; 27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pProbe = &sPk; 27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wsFlagMask = ~( 27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE 27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eqTermMask = WO_EQ|WO_IN; 27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx = 0; 27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Loop over all indices looking for the best one to use 27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(; pProbe; pIdx=pProbe=pProbe->pNext){ 27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned int * const aiRowEst = pProbe->aiRowEst; 27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double cost; /* Cost of using pProbe */ 27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double nRow; /* Estimated number of rows in result set */ 27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double log10N; /* base-10 logarithm of nRow (inexact) */ 27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rev; /* True to scan in reverse order */ 27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int wsFlags = 0; 27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask used = 0; 27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The following variables are populated based on the properties of 27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** index being evaluated. They are then used to determine the expected 27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** cost and number of rows returned. 27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** nEq: 27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Number of equality terms that can be implemented using the index. 27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** In other words, the number of initial fields in the index that 27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** are used in == or IN or NOT NULL constraints of the WHERE clause. 27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** nInMul: 27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The "in-multiplier". This is an estimate of how many seek operations 27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** SQLite must perform on the index in question. For example, if the 27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** WHERE clause is: 27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** WHERE a IN (1, 2, 3) AND b IN (4, 5, 6) 27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** SQLite must perform 9 lookups on an index on (a, b), so nInMul is 27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** set to 9. Given the same schema and either of the following WHERE 27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** clauses: 27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** WHERE a = 1 27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** WHERE a >= 2 27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** nInMul is set to 1. 27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** If there exists a WHERE term of the form "x IN (SELECT ...)", then 27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the sub-select is assumed to return 25 rows for the purposes of 27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** determining nInMul. 27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** bInEst: 27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Set to true if there was at least one "x IN (SELECT ...)" term used 27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** in determining the value of nInMul. Note that the RHS of the 27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** IN operator must be a SELECT, not a value list, for this variable 27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** to be true. 27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** estBound: 27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** An estimate on the amount of the table that must be searched. A 28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** value of 100 means the entire table is searched. Range constraints 28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** might reduce this to a value less than 100 to indicate that only 28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** a fraction of the table needs searching. In the absence of 28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** sqlite_stat2 ANALYZE data, a single inequality reduces the search 28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** space to 1/4rd its original size. So an x>? constraint reduces 28055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** estBound to 25. Two constraints (x>? AND x<?) reduce estBound to 6. 28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** bSort: 28085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Boolean. True if there is an ORDER BY clause that will require an 28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** external sort (i.e. scanning the index being evaluated will not 28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** correctly order records). 28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** bLookup: 28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Boolean. True if a table lookup is required for each index entry 28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** visited. In other words, true if this is not a covering index. 28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** This is always false for the rowid primary key index of a table. 28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** For other indexes, it is true unless all the columns of the table 28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** used by the SELECT statement are present in the index (such an 28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** index is sometimes described as a covering index). 28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** For example, given the index on (a, b), the second of the following 28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** two queries requires table b-tree lookups in order to find the value 28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** of column c, but the first does not because columns a and b are 28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** both available in the index. 28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** SELECT a, b FROM tbl WHERE a = 1; 28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** SELECT a, b, c FROM tbl WHERE a = 1; 28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nEq; /* Number of == or IN terms matching index */ 28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bInEst = 0; /* True if "x IN (SELECT...)" seen */ 28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nInMul = 1; /* Number of distinct equalities to lookup */ 28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int estBound = 100; /* Estimated reduction in search space */ 28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nBound = 0; /* Number of range constraints seen */ 28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bSort = 0; /* True if external sort required */ 28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bLookup = 0; /* True if not a covering index */ 28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTerm; /* A single term of the WHERE clause */ 28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2 28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pFirstTerm = 0; /* First term matching the index */ 28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Determine the values of nEq and nInMul */ 28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(nEq=0; nEq<pProbe->nColumn; nEq++){ 28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j = pProbe->aiColumn[nEq]; 28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx); 28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm==0 ) break; 28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ); 28455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->eOperator & WO_IN ){ 28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pExpr = pTerm->pExpr; 28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wsFlags |= WHERE_COLUMN_IN; 28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ExprHasProperty(pExpr, EP_xIsSelect) ){ 28495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* "x IN (SELECT ...)": Assume the SELECT returns 25 rows */ 28505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nInMul *= 25; 28515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bInEst = 1; 28525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ 28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* "x IN (value, value, ...)" */ 28545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nInMul *= pExpr->x.pList->nExpr; 28555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( pTerm->eOperator & WO_ISNULL ){ 28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wsFlags |= WHERE_COLUMN_NULL; 28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2 28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm; 28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) used |= pTerm->prereqRight; 28635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Determine the value of estBound. */ 28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nEq<pProbe->nColumn && pProbe->bUnordered==0 ){ 28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j = pProbe->aiColumn[nEq]; 28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){ 28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx); 28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx); 28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &estBound); 28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTop ){ 28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nBound = 1; 28745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wsFlags |= WHERE_TOP_LIMIT; 28755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) used |= pTop->prereqRight; 28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pBtm ){ 28785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nBound++; 28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wsFlags |= WHERE_BTM_LIMIT; 28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) used |= pBtm->prereqRight; 28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE); 28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( pProbe->onError!=OE_None ){ 28855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( wsFlags & WHERE_COLUMN_IN ); 28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( wsFlags & WHERE_COLUMN_NULL ); 28875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){ 28885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wsFlags |= WHERE_UNIQUE; 28895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If there is an ORDER BY clause and the index being considered will 28935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** naturally scan rows in the required order, set the appropriate flags 28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index 28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** will scan rows in a different order, set the bSort variable. */ 28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOrderBy ){ 28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (wsFlags & WHERE_COLUMN_IN)==0 28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && pProbe->bUnordered==0 28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && isSortingIndex(pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy, 29005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nEq, wsFlags, &rev) 29015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 29025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY; 29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wsFlags |= (rev ? WHERE_REVERSE : 0); 29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bSort = 1; 29065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If currently calculating the cost of using an index (not the IPK 29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** index), determine if all required column data may be obtained without 29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** using the main table (i.e. if the index is a covering 29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** index for this query). If it is, set the WHERE_IDX_ONLY flag in 29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** wsFlags. Otherwise, set the bLookup variable to true. */ 29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pIdx && wsFlags ){ 29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask m = pSrc->colUsed; 29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 29175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<pIdx->nColumn; j++){ 29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x = pIdx->aiColumn[j]; 29195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( x<BMS-1 ){ 29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m &= ~(((Bitmask)1)<<x); 29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( m==0 ){ 29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wsFlags |= WHERE_IDX_ONLY; 29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bLookup = 1; 29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Estimate the number of rows of output. For an "x IN (SELECT...)" 29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** constraint, do not let the estimate exceed half the rows in the table. 29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRow = (double)(aiRowEst[nEq] * nInMul); 29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( bInEst && nRow*2>aiRowEst[0] ){ 29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRow = aiRowEst[0]/2; 29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nInMul = (int)(nRow / aiRowEst[nEq]); 29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2 29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the constraint is of the form x=VALUE and histogram 29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** data is available for column x, then it might be possible 29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** to get a better estimate on the number of rows based on 29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** VALUE and how common that value is according to the histogram. 29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nRow>(double)1 && nEq==1 && pFirstTerm!=0 ){ 29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){ 29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pFirstTerm->eOperator==WO_EQ ); 29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pFirstTerm->eOperator==WO_ISNULL ); 29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, &nRow); 29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( pFirstTerm->eOperator==WO_IN && bInEst==0 ){ 29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, &nRow); 29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_ENABLE_STAT2 */ 29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Adjust the number of output rows and downward to reflect rows 29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** that are excluded by range constraints. 29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRow = (nRow * (double)estBound) / (double)100; 29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nRow<1 ) nRow = 1; 29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Experiments run on real SQLite databases show that the time needed 29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** to do a binary search to locate a row in a table or index is roughly 29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** log10(N) times the time to move from one row to the next row within 29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** a table or index. The actual times can vary, with the size of 29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** records being an important factor. Both moves and searches are 29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** slower with larger records, presumably because fewer records fit 29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** on one page and hence more pages have to be fetched. 29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The ANALYZE command and the sqlite_stat1 and sqlite_stat2 tables do 29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** not give us data on the relative sizes of table and index records. 29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** So this computation assumes table records are about twice as big 29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** as index records 29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (wsFlags & WHERE_NOT_FULLSCAN)==0 ){ 29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The cost of a full table scan is a number of move operations equal 29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** to the number of rows in the table. 29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** We add an additional 4x penalty to full table scans. This causes 29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the cost function to err on the side of choosing an index over 29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** choosing a full scan. This 4x full-scan penalty is an arguable 29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** decision and one which we expect to revisit in the future. But 29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** it seems to be working well enough at the moment. 29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cost = aiRowEst[0]*4; 29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log10N = estLog(aiRowEst[0]); 29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cost = nRow; 29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pIdx ){ 29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( bLookup ){ 29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* For an index lookup followed by a table lookup: 29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** nInMul index searches to find the start of each index range 29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** + nRow steps through the index 29955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** + nRow table searches to lookup the table entry using the rowid 29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cost += (nInMul + nRow)*log10N; 29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* For a covering index: 30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** nInMul index searches to find the initial entry 30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** + nRow steps through the index 30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cost += nInMul*log10N; 30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* For a rowid primary key lookup: 30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** nInMult table searches to find the initial entry for each range 30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** + nRow steps through the table 30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cost += nInMul*log10N; 30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Add in the estimated cost of sorting the result. Actual experimental 30155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** measurements of sorting performance in SQLite show that sorting time 30165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** adds C*N*log10(N) to the cost, where N is the number of rows to be 30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** sorted and C is a factor between 1.95 and 4.3. We will split the 30185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** difference and select C of 3.0. 30195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 30205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( bSort ){ 30215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cost += nRow*estLog(nRow)*3; 30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /**** Cost of using this index has now been computed ****/ 30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If there are additional constraints on this table that cannot 30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** be used with the current index, but which might lower the number 30285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** of output rows, adjust the nRow value accordingly. This only 30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** matters if the current index is the least costly, so do not bother 30305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** with this step if we already know this index will not be chosen. 30315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Also, never reduce the output row count below 2 using this step. 30325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 30335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** It is critical that the notValid mask be used here instead of 30345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the notReady mask. When computing an "optimal" index, the notReady 30355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** mask will only have one bit set - the bit for the current table. 30365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The notValid mask, on the other hand, always has all bits set for 30375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** tables that are not in outer loops. If notReady is used here instead 30385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** of notValid, then a optimal index that depends on inner joins loops 30395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** might be selected even when there exists an optimal index that has 30405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** no such dependency. 30415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 30425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nRow>2 && cost<=pCost->rCost ){ 30435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int k; /* Loop counter */ 30445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nSkipEq = nEq; /* Number of == constraints to skip */ 30455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nSkipRange = nBound; /* Number of < constraints to skip */ 30465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask thisTab; /* Bitmap for pSrc */ 30475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thisTab = getMask(pWC->pMaskSet, iCur); 30495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(pTerm=pWC->a, k=pWC->nTerm; nRow>2 && k; k--, pTerm++){ 30505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->wtFlags & TERM_VIRTUAL ) continue; 30515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pTerm->prereqAll & notValid)!=thisTab ) continue; 30525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){ 30535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nSkipEq ){ 30545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Ignore the first nEq equality matches since the index 30555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** has already accounted for these */ 30565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nSkipEq--; 30575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 30585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Assume each additional equality match reduces the result 30595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** set size by a factor of 10 */ 30605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRow /= 10; 30615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( pTerm->eOperator & (WO_LT|WO_LE|WO_GT|WO_GE) ){ 30635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nSkipRange ){ 30645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Ignore the first nSkipRange range constraints since the index 30655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** has already accounted for these */ 30665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nSkipRange--; 30675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 30685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Assume each additional range constraint reduces the result 30695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** set size by a factor of 3. Indexed range constraints reduce 30705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the search space by a larger factor: 4. We make indexed range 30715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** more selective intentionally because of the subjective 30725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** observation that indexed range constraints really are more 30735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** selective in practice, on average. */ 30745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRow /= 3; 30755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( pTerm->eOperator!=WO_NOOP ){ 30775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Any other expression lowers the output row count by half */ 30785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRow /= 2; 30795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nRow<2 ) nRow = 2; 30825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(( 30865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%s(%s): nEq=%d nInMul=%d estBound=%d bSort=%d bLookup=%d wsFlags=0x%x\n" 30875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n", 30885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), 30895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nEq, nInMul, estBound, bSort, bLookup, wsFlags, 30905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notReady, log10N, nRow, cost, used 30915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) )); 30925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If this index is the best we have seen so far, then record this 30945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** index and its cost in the pCost structure. 30955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 30965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (!pIdx || wsFlags) 30975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (cost<pCost->rCost || (cost<=pCost->rCost && nRow<pCost->plan.nRow)) 30985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 30995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->rCost = cost; 31005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->used = used; 31015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.nRow = nRow; 31025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.wsFlags = (wsFlags&wsFlagMask); 31035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.nEq = nEq; 31045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.u.pIdx = pIdx; 31055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If there was an INDEXED BY clause, then only that one index is 31085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** considered. */ 31095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pSrc->pIndex ) break; 31105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Reset masks for the next index in the loop */ 31125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE); 31135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eqTermMask = idxEqTermMask; 31145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag 31175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is set, then reverse the order that the index will be scanned 31185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** in. This is used for application testing, to help find cases 31195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** where application behaviour depends on the (undefined) order that 31205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** SQLite outputs rows in in the absence of an ORDER BY clause. */ 31215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){ 31225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.wsFlags |= WHERE_REVERSE; 31235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pOrderBy || (pCost->plan.wsFlags&WHERE_ORDERBY)==0 ); 31265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pCost->plan.u.pIdx==0 || (pCost->plan.wsFlags&WHERE_ROWID_EQ)==0 ); 31275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pSrc->pIndex==0 31285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || pCost->plan.u.pIdx==0 31295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || pCost->plan.u.pIdx==pSrc->pIndex 31305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 31315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("best index is: %s\n", 31335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ? "none" : 31345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk") 31355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) )); 31365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost); 31385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bestAutomaticIndex(pParse, pWC, pSrc, notReady, pCost); 31395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCost->plan.wsFlags |= eqTermMask; 31405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 31415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 31435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Find the query plan for accessing table pSrc->pTab. Write the 31445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** best query plan and its cost into the WhereCost object supplied 31455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** as the last parameter. This function may calculate the cost of 31465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** both real and virtual table scans. 31475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 31485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void bestIndex( 31495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* The parsing context */ 31505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC, /* The WHERE clause */ 31515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SrcList_item *pSrc, /* The FROM clause term to search */ 31525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notReady, /* Mask of cursors not available for indexing */ 31535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notValid, /* Cursors not available for any purpose */ 31545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprList *pOrderBy, /* The ORDER BY clause */ 31555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereCost *pCost /* Lowest cost query plan */ 31565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 31575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE 31585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( IsVirtual(pSrc->pTab) ){ 31595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_index_info *p = 0; 31605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bestVirtualIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost,&p); 31615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->needToFreeIdxStr ){ 31625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(p->idxStr); 31635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(pParse->db, p); 31655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else 31665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 31675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 31685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bestBtreeIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost); 31695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 31715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 31735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Disable a term in the WHERE clause. Except, do not disable the term 31745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** if it controls a LEFT OUTER JOIN and it did not originate in the ON 31755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** or USING clause of that join. 31765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 31775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Consider the term t2.z='ok' in the following queries: 31785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 31795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (1) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok' 31805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok' 31815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok' 31825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 31835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The t2.z='ok' is disabled in the in (2) because it originates 31845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in the ON clause. The term is disabled in (3) because it is not part 31855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of a LEFT OUTER JOIN. In (1), the term is not disabled. 31865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 31875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** IMPLEMENTATION-OF: R-24597-58655 No tests are done for terms that are 31885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** completely satisfied by indices. 31895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 31905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Disabling a term causes that term to not be tested in the inner loop 31915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of the join. Disabling is an optimization. When terms are satisfied 31925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** by indices, we disable them to prevent redundant tests in the inner 31935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** loop. We would get the correct results if nothing were ever disabled, 31945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** but joins might run a little slower. The trick is to disable as much 31955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** as we can without disabling too much. If we disabled in (1), we'd get 31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the wrong answer. See ticket #813. 31975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 31985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ 31995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm 32005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (pTerm->wtFlags & TERM_CODED)==0 32015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) 32025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 32035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->wtFlags |= TERM_CODED; 32045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->iParent>=0 ){ 32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent]; 32065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (--pOther->nChild)==0 ){ 32075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disableTerm(pLevel, pOther); 32085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Code an OP_Affinity opcode to apply the column affinity string zAff 32155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to the n registers starting at base. 32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** As an optimization, SQLITE_AFF_NONE entries (which are no-ops) at the 32185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** beginning and end of zAff are ignored. If all entries in zAff are 32195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SQLITE_AFF_NONE, then no code gets generated. 32205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine makes its own copy of zAff so that the caller is free 32225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to modify zAff after this routine returns. 32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 32245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ 32255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vdbe *v = pParse->pVdbe; 32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( zAff==0 ){ 32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pParse->db->mallocFailed ); 32285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 32295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( v!=0 ); 32315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Adjust base and n to skip over SQLITE_AFF_NONE entries at the beginning 32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** and end of the affinity string. 32345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 32355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( n>0 && zAff[0]==SQLITE_AFF_NONE ){ 32365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n--; 32375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base++; 32385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zAff++; 32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( n>1 && zAff[n-1]==SQLITE_AFF_NONE ){ 32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n--; 32425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Code the OP_Affinity opcode if there is anything left to do. */ 32455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( n>0 ){ 32465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Affinity, base, n); 32475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeChangeP4(v, -1, zAff, n); 32485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCacheAffinityChange(pParse, base, n); 32495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 32515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 32545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate code for a single equality term of the WHERE clause. An equality 32555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** term can be either X=expr or X IN (...). pTerm is the term to be 32565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** coded. 32575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 32585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The current value for the constraint is left in register iReg. 32595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 32605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** For a constraint of the form X=expr, the expression is evaluated and its 32615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** result is left on the stack. For constraints of the form X IN (...) 32625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** this routine sets up a loop that will iterate over all values of X. 32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 32645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int codeEqualityTerm( 32655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* The parsing context */ 32665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ 32675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereLevel *pLevel, /* When level of the FROM clause we are working on */ 32685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iTarget /* Attempt to leave results in this register */ 32695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 32705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pX = pTerm->pExpr; 32715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vdbe *v = pParse->pVdbe; 32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iReg; /* Register holding results */ 32735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( iTarget>0 ); 32755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pX->op==TK_EQ ){ 32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); 32775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( pX->op==TK_ISNULL ){ 32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iReg = iTarget; 32795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); 32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_SUBQUERY 32815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 32825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int eType; 32835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iTab; 32845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct InLoop *pIn; 32855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pX->op==TK_IN ); 32875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iReg = iTarget; 32885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eType = sqlite3FindInIndex(pParse, pX, 0); 32895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iTab = pX->iTable; 32905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); 32915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pLevel->plan.wsFlags & WHERE_IN_ABLE ); 32925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->u.in.nIn==0 ){ 32935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->addrNxt = sqlite3VdbeMakeLabel(v); 32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->u.in.nIn++; 32965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->u.in.aInLoop = 32975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop, 32985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); 32995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIn = pLevel->u.in.aInLoop; 33005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pIn ){ 33015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIn += pLevel->u.in.nIn - 1; 33025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIn->iCur = iTab; 33035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( eType==IN_INDEX_ROWID ){ 33045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg); 33055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 33065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg); 33075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp1(v, OP_IsNull, iReg); 33095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 33105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->u.in.nIn = 0; 33115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 33135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disableTerm(pLevel, pTerm); 33155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iReg; 33165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 33175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 33195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate code that will evaluate all == and IN constraints for an 33205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** index. 33215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 33225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c). 33235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Suppose the WHERE clause is this: a==5 AND b IN (1,2,3) AND c>5 AND c<10 33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The index has as many as three equality constraints, but in this 33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** example, the third "c" value is an inequality. So only two 33265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** constraints are coded. This routine will generate code to evaluate 33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a==5 and b IN (1,2,3). The current values for a and b will be stored 33285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in consecutive registers and the index of the first register is returned. 33295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** In the example above nEq==2. But this subroutine works for any value 33315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of nEq including 0. If nEq==0, this routine is nearly a no-op. 33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The only thing it does is allocate the pLevel->iMem memory cell and 33335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** compute the affinity string. 33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 33355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine always allocates at least one memory cell and returns 33365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the index of that memory cell. The code that 33375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** calls this routine will use that memory cell to store the termination 33385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** key value of the loop. If one or more IN operators appear, then 33395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** this routine allocates an additional nEq memory cells for internal 33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** use. 33415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 33425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Before returning, *pzAff is set to point to a buffer containing a 33435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** copy of the column affinity string of the index allocated using 33445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3DbMalloc(). Except, entries in the copy of the string associated 33455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** with equality constraints that use NONE affinity are set to 33465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SQLITE_AFF_NONE. This is to deal with SQL such as the following: 33475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 33485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** CREATE TABLE t1(a TEXT PRIMARY KEY, b); 33495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SELECT ... FROM t1 AS t2, t1 WHERE t1.a = t2.b; 33505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 33515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** In the example above, the index on t1(a) has TEXT affinity. But since 33525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the right hand side of the equality constraint (t2.b) has NONE affinity, 33535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** no conversion should be attempted before using a t2.b value as part of 33545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a key to search the index. Hence the first byte in the returned affinity 33555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** string in this example would be set to SQLITE_AFF_NONE. 33565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 33575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int codeAllEqualityTerms( 33585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* Parsing context */ 33595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */ 33605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC, /* The WHERE clause */ 33615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notReady, /* Which parts of FROM have not yet been coded */ 33625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nExtraReg, /* Number of extra registers to allocate */ 33635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char **pzAff /* OUT: Set to point to affinity string */ 33645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 33655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nEq = pLevel->plan.nEq; /* The number of == or IN constraints to code */ 33665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vdbe *v = pParse->pVdbe; /* The vm under construction */ 33675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *pIdx; /* The index being used for this loop */ 33685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iCur = pLevel->iTabCur; /* The cursor of the table */ 33695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTerm; /* A single constraint term */ 33705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; /* Loop counter */ 33715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int regBase; /* Base register */ 33725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nReg; /* Number of registers to allocate */ 33735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zAff; /* Affinity string to return */ 33745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This module is only called on query plans that use an index. */ 33765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pLevel->plan.wsFlags & WHERE_INDEXED ); 33775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx = pLevel->plan.u.pIdx; 33785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Figure out how many memory cells we will need then allocate them. 33805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 33815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regBase = pParse->nMem + 1; 33825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nReg = pLevel->plan.nEq + nExtraReg; 33835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pParse->nMem += nReg; 33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx)); 33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !zAff ){ 33875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pParse->db->mallocFailed = 1; 33885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Evaluate the equality constraints 33915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 33925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pIdx->nColumn>=nEq ); 33935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<nEq; j++){ 33945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int r1; 33955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int k = pIdx->aiColumn[j]; 33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = findTerm(pWC, iCur, k, notReady, pLevel->plan.wsFlags, pIdx); 33975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( NEVER(pTerm==0) ) break; 33985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The following true for indices with redundant columns. 33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */ 34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( (pTerm->wtFlags & TERM_CODED)!=0 ); 34015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ 34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r1 = codeEqualityTerm(pParse, pTerm, pLevel, regBase+j); 34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( r1!=regBase+j ){ 34045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nReg==1 ){ 34055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ReleaseTempReg(pParse, regBase); 34065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regBase = r1; 34075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 34085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j); 34095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTerm->eOperator & WO_ISNULL ); 34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTerm->eOperator & WO_IN ); 34135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){ 34145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pRight = pTerm->pExpr->pRight; 34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCodeIsNullJump(v, pRight, regBase+j, pLevel->addrBrk); 34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( zAff ){ 34175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_NONE ){ 34185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zAff[j] = SQLITE_AFF_NONE; 34195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){ 34215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zAff[j] = SQLITE_AFF_NONE; 34225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pzAff = zAff; 34275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return regBase; 34285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 34295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_EXPLAIN 34315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 34325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine is a helper for explainIndexRange() below 34335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 34345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** pStr holds the text of an expression that we are building up one term 34355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** at a time. This routine adds a new term to the end of the expression. 34365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Terms are separated by AND so add the "AND" text for second and subsequent 34375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** terms only. 34385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 34395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void explainAppendTerm( 34405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StrAccum *pStr, /* The text expression being built */ 34415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iTerm, /* Index of this term. First is zero */ 34425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zColumn, /* Name of the column */ 34435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zOp /* Name of the operator */ 34445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 34455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( iTerm ) sqlite3StrAccumAppend(pStr, " AND ", 5); 34465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3StrAccumAppend(pStr, zColumn, -1); 34475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3StrAccumAppend(pStr, zOp, 1); 34485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3StrAccumAppend(pStr, "?", 1); 34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 34525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Argument pLevel describes a strategy for scanning table pTab. This 34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** function returns a pointer to a string buffer containing a description 34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of the subset of table rows scanned by the strategy in the form of an 34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SQL expression. Or, if all rows are scanned, NULL is returned. 34565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 34575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** For example, if the query: 34585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 34595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SELECT * FROM t1 WHERE a=1 AND b>2; 34605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 34615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is run and there is an index on (a, b), then this function returns a 34625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** string similar to: 34635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 34645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** "a=? AND b>?" 34655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 34665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The returned pointer points to memory obtained from sqlite3DbMalloc(). 34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** It is the responsibility of the caller to free the buffer when it is 34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** no longer required. 34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 34705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char *explainIndexRange(sqlite3 *db, WhereLevel *pLevel, Table *pTab){ 34715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WherePlan *pPlan = &pLevel->plan; 34725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *pIndex = pPlan->u.pIdx; 34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nEq = pPlan->nEq; 34745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j; 34755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Column *aCol = pTab->aCol; 34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *aiColumn = pIndex->aiColumn; 34775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StrAccum txt; 34785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nEq==0 && (pPlan->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){ 34805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 34815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH); 34835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) txt.db = db; 34845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3StrAccumAppend(&txt, " (", 2); 34855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<nEq; i++){ 34865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explainAppendTerm(&txt, i, aCol[aiColumn[i]].zName, "="); 34875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = i; 34905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pPlan->wsFlags&WHERE_BTM_LIMIT ){ 34915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explainAppendTerm(&txt, i++, aCol[aiColumn[j]].zName, ">"); 34925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pPlan->wsFlags&WHERE_TOP_LIMIT ){ 34945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explainAppendTerm(&txt, i, aCol[aiColumn[j]].zName, "<"); 34955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3StrAccumAppend(&txt, ")", 1); 34975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sqlite3StrAccumFinish(&txt); 34985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 34995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 35015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN 35025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single 35035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** record is added to the output to describe the table scan strategy in 35045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** pLevel. 35055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 35065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void explainOneScan( 35075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* Parse context */ 35085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SrcList *pTabList, /* Table list this loop refers to */ 35095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ 35105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iLevel, /* Value for "level" column of output */ 35115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iFrom, /* Value for "from" column of output */ 35125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ 35135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 35145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pParse->explain==2 ){ 35155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u32 flags = pLevel->plan.wsFlags; 35165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; 35175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vdbe *v = pParse->pVdbe; /* VM being constructed */ 35185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db = pParse->db; /* Database handle */ 35195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zMsg; /* Text to add to EQP output */ 35205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_int64 nRow; /* Expected number of rows visited by scan */ 35215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iId = pParse->iSelectId; /* Select id (left-most output column) */ 35225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isSearch; /* True for a SEARCH. False for SCAN. */ 35235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return; 35255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isSearch = (pLevel->plan.nEq>0) 35275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 35285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); 35295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN"); 35315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pItem->pSelect ){ 35325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId); 35335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 35345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zMsg = sqlite3MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName); 35355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pItem->zAlias ){ 35385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias); 35395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (flags & WHERE_INDEXED)!=0 ){ 35415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zWhere = explainIndexRange(db, pLevel, pItem->pTab); 35425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg, 35435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""), 35445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((flags & WHERE_IDX_ONLY)?"COVERING ":""), 35455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((flags & WHERE_TEMP_INDEX)?"":" "), 35465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((flags & WHERE_TEMP_INDEX)?"": pLevel->plan.u.pIdx->zName), 35475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zWhere 35485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 35495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(db, zWhere); 35505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ 35515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg); 35525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( flags&WHERE_ROWID_EQ ){ 35545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg); 35555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){ 35565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg); 35575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( flags&WHERE_BTM_LIMIT ){ 35585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg); 35595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( flags&WHERE_TOP_LIMIT ){ 35605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg); 35615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE 35645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ 35655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx; 35665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg, 35675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pVtabIdx->idxNum, pVtabIdx->idxStr); 35685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 35705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) ){ 35715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( wctrlFlags & WHERE_ORDERBY_MIN ); 35725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRow = 1; 35735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 35745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRow = (sqlite3_int64)pLevel->plan.nRow; 35755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zMsg = sqlite3MAppendf(db, zMsg, "%s (~%lld rows)", zMsg, nRow); 35775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC); 35785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 35805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 35815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define explainOneScan(u,v,w,x,y,z) 35825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_EXPLAIN */ 35835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 35865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate code for the start of the iLevel-th loop in the WHERE clause 35875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** implementation described by pWInfo. 35885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 35895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Bitmask codeOneLoopStart( 35905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereInfo *pWInfo, /* Complete information about the WHERE clause */ 35915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iLevel, /* Which level of pWInfo->a[] should be coded */ 35925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */ 35935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notReady /* Which tables are currently available */ 35945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 35955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j, k; /* Loop counters */ 35965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iCur; /* The VDBE cursor for the table */ 35975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int addrNxt; /* Where to jump to continue with the next IN case */ 35985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int omitTable; /* True if we use the index only */ 35995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bRev; /* True if we need to scan in reverse order */ 36005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereLevel *pLevel; /* The where level to be coded */ 36015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC; /* Decomposition of the entire WHERE clause */ 36025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pTerm; /* A WHERE clause term */ 36035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse; /* Parsing context */ 36045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vdbe *v; /* The prepared stmt under constructions */ 36055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SrcList_item *pTabItem; /* FROM clause term being coded */ 36065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int addrBrk; /* Jump here to break out of the loop */ 36075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int addrCont; /* Jump here to continue with next cycle */ 36085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iRowidReg = 0; /* Rowid is stored in this register, if not zero */ 36095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iReleaseReg = 0; /* Temp register to free before returning */ 36105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pParse = pWInfo->pParse; 36125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v = pParse->pVdbe; 36135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC = pWInfo->pWC; 36145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel = &pWInfo->a[iLevel]; 36155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; 36165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iCur = pTabItem->iCursor; 36175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0; 36185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0 36195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (wctrlFlags & WHERE_FORCE_TABLE)==0; 36205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Create labels for the "break" and "continue" instructions 36225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** for the current loop. Jump to addrBrk to break out of a loop. 36235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Jump to cont to go immediately to the next iteration of the 36245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** loop. 36255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 36265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** When there is an IN operator, we also have a "addrNxt" label that 36275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** means to continue with the next IN value combination. When 36285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** there are no IN operators in the constraints, the "addrNxt" label 36295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is the same as "addrBrk". 36305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 36315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(v); 36325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(v); 36335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If this is the right table of a LEFT OUTER JOIN, allocate and 36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** initialize a memory cell that records if this table matches any 36365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** row of the left table of the join. 36375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 36385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){ 36395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->iLeftJoin = ++pParse->nMem; 36405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); 36415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VdbeComment((v, "init LEFT JOIN no-match flag")); 36425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE 36455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){ 36465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Case 0: The table is a virtual-table. Use the VFilter and VNext 36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** to access the data. 36485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 36495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iReg; /* P3 Value for OP_VFilter */ 36505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx; 36515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nConstraint = pVtabIdx->nConstraint; 36525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sqlite3_index_constraint_usage *aUsage = 36535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pVtabIdx->aConstraintUsage; 36545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sqlite3_index_constraint *aConstraint = 36555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pVtabIdx->aConstraint; 36565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCachePush(pParse); 36585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iReg = sqlite3GetTempRange(pParse, nConstraint+2); 36595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=1; j<=nConstraint; j++){ 36605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(k=0; k<nConstraint; k++){ 36615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( aUsage[k].argvIndex==j ){ 36625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iTerm = aConstraint[k].iTermOffset; 36635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCode(pParse, pWC->a[iTerm].pExpr->pRight, iReg+j+1); 36645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 36655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( k==nConstraint ) break; 36685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Integer, pVtabIdx->idxNum, iReg); 36705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1); 36715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrBrk, iReg, pVtabIdx->idxStr, 36725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pVtabIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC); 36735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pVtabIdx->needToFreeIdxStr = 0; 36745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<nConstraint; j++){ 36755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( aUsage[j].omit ){ 36765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iTerm = aConstraint[j].iTermOffset; 36775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disableTerm(pLevel, &pWC->a[iTerm]); 36785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->op = OP_VNext; 36815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->p1 = iCur; 36825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->p2 = sqlite3VdbeCurrentAddr(v); 36835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); 36845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCachePop(pParse, 1); 36855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else 36865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_VIRTUALTABLE */ 36875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->plan.wsFlags & WHERE_ROWID_EQ ){ 36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Case 1: We can directly reference a single row using an 36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** equality comparison against the ROWID field. Or 36915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** we reference multiple rows using a "rowid IN (...)" 36925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** construct. 36935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iReleaseReg = sqlite3GetTempReg(pParse); 36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0); 36965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pTerm!=0 ); 36975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pTerm->pExpr!=0 ); 36985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pTerm->leftCursor==iCur ); 36995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( omitTable==0 ); 37005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ 37015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, iReleaseReg); 37025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addrNxt = pLevel->addrNxt; 37035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); 37045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg); 37055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); 37065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VdbeComment((v, "pk")); 37075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->op = OP_Noop; 37085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( pLevel->plan.wsFlags & WHERE_ROWID_RANGE ){ 37095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Case 2: We have an inequality comparison against the ROWID field. 37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int testOp = OP_Noop; 37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start; 37135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int memEndValue = 0; 37145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pStart, *pEnd; 37155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( omitTable==0 ); 37175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pStart = findTerm(pWC, iCur, -1, notReady, WO_GT|WO_GE, 0); 37185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pEnd = findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE, 0); 37195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( bRev ){ 37205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = pStart; 37215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pStart = pEnd; 37225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pEnd = pTerm; 37235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pStart ){ 37255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pX; /* The expression that defines the start bound */ 37265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int r1, rTemp; /* Registers for holding the start boundary */ 37275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The following constant maps TK_xx codes into corresponding 37295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** seek opcodes. It depends on a particular ordering of TK_xx 37305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 37315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const u8 aMoveOp[] = { 37325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TK_GT */ OP_SeekGt, 37335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TK_LE */ OP_SeekLe, 37345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TK_LT */ OP_SeekLt, 37355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TK_GE */ OP_SeekGe 37365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 37375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */ 37385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ 37395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( TK_GE==TK_GT+3 ); /* ... is correcct. */ 37405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ 37425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pX = pStart->pExpr; 37435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pX!=0 ); 37445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pStart->leftCursor==iCur ); 37455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); 37465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1); 37475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VdbeComment((v, "pk")); 37485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCacheAffinityChange(pParse, r1, 1); 37495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ReleaseTempReg(pParse, rTemp); 37505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disableTerm(pLevel, pStart); 37515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 37525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk); 37535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pEnd ){ 37555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pX; 37565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pX = pEnd->pExpr; 37575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pX!=0 ); 37585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pEnd->leftCursor==iCur ); 37595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ 37605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memEndValue = ++pParse->nMem; 37615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCode(pParse, pX->pRight, memEndValue); 37625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pX->op==TK_LT || pX->op==TK_GT ){ 37635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testOp = bRev ? OP_Le : OP_Ge; 37645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 37655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testOp = bRev ? OP_Lt : OP_Gt; 37665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disableTerm(pLevel, pEnd); 37685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start = sqlite3VdbeCurrentAddr(v); 37705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->op = bRev ? OP_Prev : OP_Next; 37715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->p1 = iCur; 37725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->p2 = start; 37735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pStart==0 && pEnd==0 ){ 37745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; 37755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 37765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pLevel->p5==0 ); 37775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( testOp!=OP_Noop ){ 37795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse); 37805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg); 37815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); 37825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg); 37835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); 37845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( pLevel->plan.wsFlags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ) ){ 37865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Case 3: A scan using an index. 37875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 37885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The WHERE clause may contain zero or more equality 37895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** terms ("==" or "IN" operators) that refer to the N 37905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** left-most columns of the index. It may also contain 37915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** inequality constraints (>, <, >= or <=) on the indexed 37925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** column that immediately follows the N equalities. Only 37935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the right-most column can be an inequality - the rest must 37945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** use the "==" and "IN" operators. For example, if the 37955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** index is on (x,y,z), then the following clauses are all 37965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** optimized: 37975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 37985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** x=5 37995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** x=5 AND y=10 38005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** x=5 AND y<10 38015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** x=5 AND y>5 AND y<10 38025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** x=5 AND y=5 AND z<=10 38035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 38045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The z<10 term of the following cannot be used, only 38055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the x=5 term: 38065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 38075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** x=5 AND z<10 38085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 38095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** N may be zero if there are inequality constraints. 38105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** If there are no inequality constraints, then N is at 38115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** least one. 38125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 38135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** This case is also used when there are no WHERE clause 38145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** constraints but an index is selected anyway, in order 38155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** to force the output order to conform to an ORDER BY. 38165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 38175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const u8 aStartOp[] = { 38185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 38195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 38205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */ 38215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OP_Last, /* 3: (!start_constraints && startEq && bRev) */ 38225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OP_SeekGt, /* 4: (start_constraints && !startEq && !bRev) */ 38235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OP_SeekLt, /* 5: (start_constraints && !startEq && bRev) */ 38245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OP_SeekGe, /* 6: (start_constraints && startEq && !bRev) */ 38255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OP_SeekLe /* 7: (start_constraints && startEq && bRev) */ 38265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 38275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const u8 aEndOp[] = { 38285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OP_Noop, /* 0: (!end_constraints) */ 38295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OP_IdxGE, /* 1: (end_constraints && !bRev) */ 38305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OP_IdxLT /* 2: (end_constraints && bRev) */ 38315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 38325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nEq = pLevel->plan.nEq; /* Number of == or IN terms */ 38335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */ 38345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int regBase; /* Base register holding constraint values */ 38355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int r1; /* Temp register */ 38365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */ 38375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */ 38385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int startEq; /* True if range start uses ==, >= or <= */ 38395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int endEq; /* True if range end uses ==, >= or <= */ 38405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start_constraints; /* Start of range is constrained */ 38415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nConstraint; /* Number of constraint terms */ 38425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *pIdx; /* The index we will be using */ 38435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iIdxCur; /* The VDBE cursor for the index */ 38445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nExtraReg = 0; /* Number of extra registers needed */ 38455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int op; /* Instruction opcode */ 38465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zStartAff; /* Affinity for start of range constraint */ 38475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zEndAff; /* Affinity for end of range constraint */ 38485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx = pLevel->plan.u.pIdx; 38505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iIdxCur = pLevel->iIdxCur; 38515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) k = pIdx->aiColumn[nEq]; /* Column for inequality constraints */ 38525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If this loop satisfies a sort order (pOrderBy) request that 38545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** was passed to this function to implement a "SELECT min(x) ..." 38555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** query, then the caller will only allow the loop to run for 38565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** a single iteration. This means that the first row returned 38575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** should not have a NULL value stored in 'x'. If column 'x' is 38585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the first one after the nEq equality constraints in the index, 38595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** this requires some special handling. 38605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 38615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (wctrlFlags&WHERE_ORDERBY_MIN)!=0 38625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (pLevel->plan.wsFlags&WHERE_ORDERBY) 38635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (pIdx->nColumn>nEq) 38645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 38655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* assert( pOrderBy->nExpr==1 ); */ 38665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* assert( pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq] ); */ 38675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isMinQuery = 1; 38685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nExtraReg = 1; 38695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Find any inequality constraint terms for the start and end 38725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** of the range. 38735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 38745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->plan.wsFlags & WHERE_TOP_LIMIT ){ 38755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pRangeEnd = findTerm(pWC, iCur, k, notReady, (WO_LT|WO_LE), pIdx); 38765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nExtraReg = 1; 38775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->plan.wsFlags & WHERE_BTM_LIMIT ){ 38795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pRangeStart = findTerm(pWC, iCur, k, notReady, (WO_GT|WO_GE), pIdx); 38805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nExtraReg = 1; 38815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate code to evaluate all constraint terms using == or IN 38845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** and store the values of those terms in an array of registers 38855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** starting at regBase. 38865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 38875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regBase = codeAllEqualityTerms( 38885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pParse, pLevel, pWC, notReady, nExtraReg, &zStartAff 38895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 38905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zEndAff = sqlite3DbStrDup(pParse->db, zStartAff); 38915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addrNxt = pLevel->addrNxt; 38925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If we are doing a reverse order scan on an ascending index, or 38945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** a forward order scan on a descending index, interchange the 38955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** start and end terms (pRangeStart and pRangeEnd). 38965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 38975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){ 38985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SWAP(WhereTerm *, pRangeEnd, pRangeStart); 38995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pRangeStart && pRangeStart->eOperator & WO_LE ); 39025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pRangeStart && pRangeStart->eOperator & WO_GE ); 39035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pRangeEnd && pRangeEnd->eOperator & WO_LE ); 39045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pRangeEnd && pRangeEnd->eOperator & WO_GE ); 39055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE); 39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE); 39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_constraints = pRangeStart || nEq>0; 39085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Seek the index cursor to the start of the range. */ 39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nConstraint = nEq; 39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pRangeStart ){ 39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pRight = pRangeStart->pExpr->pRight; 39135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCode(pParse, pRight, regBase+nEq); 39145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pRangeStart->wtFlags & TERM_VNULL)==0 ){ 39155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt); 39165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( zStartAff ){ 39185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sqlite3CompareAffinity(pRight, zStartAff[nEq])==SQLITE_AFF_NONE){ 39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Since the comparison is to be performed with no conversions 39205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** applied to the operands, set the affinity to apply to pRight to 39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** SQLITE_AFF_NONE. */ 39225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zStartAff[nEq] = SQLITE_AFF_NONE; 39235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){ 39255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zStartAff[nEq] = SQLITE_AFF_NONE; 39265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nConstraint++; 39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ 39305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( isMinQuery ){ 39315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); 39325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nConstraint++; 39335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) startEq = 0; 39345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_constraints = 1; 39355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codeApplyAffinity(pParse, regBase, nConstraint, zStartAff); 39375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; 39385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( op!=0 ); 39395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( op==OP_Rewind ); 39405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( op==OP_Last ); 39415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( op==OP_SeekGt ); 39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( op==OP_SeekGe ); 39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( op==OP_SeekLe ); 39445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( op==OP_SeekLt ); 39455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); 39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Load the value for the inequality constraint at the end of the 39485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** range (if any). 39495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 39505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nConstraint = nEq; 39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pRangeEnd ){ 39525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pRight = pRangeEnd->pExpr->pRight; 39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); 39545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCode(pParse, pRight, regBase+nEq); 39555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pRangeEnd->wtFlags & TERM_VNULL)==0 ){ 39565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt); 39575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( zEndAff ){ 39595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sqlite3CompareAffinity(pRight, zEndAff[nEq])==SQLITE_AFF_NONE){ 39605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Since the comparison is to be performed with no conversions 39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** applied to the operands, set the affinity to apply to pRight to 39625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** SQLITE_AFF_NONE. */ 39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zEndAff[nEq] = SQLITE_AFF_NONE; 39645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sqlite3ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){ 39665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zEndAff[nEq] = SQLITE_AFF_NONE; 39675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codeApplyAffinity(pParse, regBase, nEq+1, zEndAff); 39705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nConstraint++; 39715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ 39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(pParse->db, zStartAff); 39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(pParse->db, zEndAff); 39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Top of the loop body */ 39775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->p2 = sqlite3VdbeCurrentAddr(v); 39785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check if the index cursor is past the end of the range. */ 39805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) op = aEndOp[(pRangeEnd || nEq) * (1 + bRev)]; 39815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( op==OP_Noop ); 39825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( op==OP_IdxGE ); 39835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( op==OP_IdxLT ); 39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( op!=OP_Noop ){ 39855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); 39865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeChangeP5(v, endEq!=bRev ?1:0); 39875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If there are inequality constraints, check that the value 39905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** of the table column that the inequality contrains is not NULL. 39915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** If it is, jump to the next iteration of the loop. 39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r1 = sqlite3GetTempReg(pParse); 39945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pLevel->plan.wsFlags & WHERE_BTM_LIMIT ); 39955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pLevel->plan.wsFlags & WHERE_TOP_LIMIT ); 39965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){ 39975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1); 39985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont); 39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ReleaseTempReg(pParse, r1); 40015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Seek the table cursor, if required */ 40035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disableTerm(pLevel, pRangeStart); 40045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disableTerm(pLevel, pRangeEnd); 40055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !omitTable ){ 40065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse); 40075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); 40085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); 40095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg); /* Deferred seek */ 40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Record the instruction used to terminate the loop. Disable 40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** WHERE clause terms made redundant by the index range scan. 40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 40155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->plan.wsFlags & WHERE_UNIQUE ){ 40165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->op = OP_Noop; 40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( bRev ){ 40185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->op = OP_Prev; 40195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 40205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->op = OP_Next; 40215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->p1 = iIdxCur; 40235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else 40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_OR_OPTIMIZATION 40265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){ 40275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Case 4: Two or more separately indexed terms connected by OR 40285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 40295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Example: 40305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 40315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** CREATE TABLE t1(a,b,c,d); 40325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** CREATE INDEX i1 ON t1(a); 40335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** CREATE INDEX i2 ON t1(b); 40345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** CREATE INDEX i3 ON t1(c); 40355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 40365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** SELECT * FROM t1 WHERE a=5 OR b=7 OR (c=11 AND d=13) 40375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 40385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** In the example, there are three indexed terms connected by OR. 40395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The top of the loop looks like this: 40405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 40415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Null 1 # Zero the rowset in reg 1 40425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 40435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Then, for each indexed term, the following. The arguments to 40445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** RowSetTest are such that the rowid of the current row is inserted 40455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** into the RowSet. If it is already present, control skips the 40465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Gosub opcode and jumps straight to the code generated by WhereEnd(). 40475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 40485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** sqlite3WhereBegin(<term>) 40495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** RowSetTest # Insert rowid into rowset 40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Gosub 2 A 40515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** sqlite3WhereEnd() 40525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 40535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Following the above, code to terminate the loop. Label A, the target 40545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** of the Gosub above, jumps to the instruction right after the Goto. 40555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Null 1 # Zero the rowset in reg 1 40575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Goto B # The loop is finished. 40585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 40595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** A: <loop body> # Return data, whatever. 40605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 40615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Return 2 # Jump back to the Gosub 40625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 40635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** B: <after the loop> 40645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 40655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 40665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pOrWc; /* The OR-clause broken out into subterms */ 40675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SrcList *pOrTab; /* Shortened table list or OR-clause generation */ 40685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */ 40705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int regRowset = 0; /* Register for RowSet object */ 40715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int regRowid = 0; /* Register holding rowid */ 40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */ 40735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iRetInit; /* Address of regReturn init */ 40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int untestedTerms = 0; /* Some terms not completely tested */ 40755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ii; 40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm = pLevel->plan.u.pTerm; 40785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pTerm!=0 ); 40795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pTerm->eOperator==WO_OR ); 40805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( (pTerm->wtFlags & TERM_ORINFO)!=0 ); 40815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrWc = &pTerm->u.pOrInfo->wc; 40825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->op = OP_Return; 40835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->p1 = regReturn; 40845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Set up a new SrcList ni pOrTab containing the table being scanned 40865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** by this loop in the a[0] slot and all notReady tables in a[1..] slots. 40875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** This becomes the SrcList in the recursive call to sqlite3WhereBegin(). 40885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 40895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pWInfo->nLevel>1 ){ 40905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nNotReady; /* The number of notReady tables */ 40915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SrcList_item *origSrc; /* Original list of tables */ 40925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nNotReady = pWInfo->nLevel - iLevel - 1; 40935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrTab = sqlite3StackAllocRaw(pParse->db, 40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); 40955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOrTab==0 ) return notReady; 40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrTab->nAlloc = (i16)(nNotReady + 1); 40975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrTab->nSrc = pOrTab->nAlloc; 40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem)); 40995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origSrc = pWInfo->pTabList->a; 41005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(k=1; k<=nNotReady; k++){ 41015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k])); 41025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 41045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrTab = pWInfo->pTabList; 41055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initialize the rowset register to contain NULL. An SQL NULL is 41085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** equivalent to an empty rowset. 41095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 41105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Also initialize regReturn to contain the address of the instruction 41115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** immediately following the OP_Return at the bottom of the loop. This 41125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is required in a few obscure LEFT JOIN cases where control jumps 41135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** over the top of the loop into the body of it. In this case the 41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** correct response for the end-of-loop code (the OP_Return) is to 41155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** fall through to the next instruction, just as an OP_Next does if 41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** called on an uninitialized cursor. 41175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 41185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ 41195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regRowset = ++pParse->nMem; 41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regRowid = ++pParse->nMem; 41215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset); 41225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn); 41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(ii=0; ii<pOrWc->nTerm; ii++){ 41265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereTerm *pOrTerm = &pOrWc->a[ii]; 41275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){ 41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereInfo *pSubWInfo; /* Info for single OR-term scan */ 41295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Loop through table entries that match term pOrTerm. */ 41305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrTerm->pExpr, 0, 41315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERE_OMIT_OPEN | WHERE_OMIT_CLOSE | 41325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY); 41335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pSubWInfo ){ 41345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explainOneScan( 41355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 41365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 41375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ 41385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); 41395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int r; 41405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r = sqlite3ExprCodeGetColumn(pParse, pTabItem->pTab, -1, iCur, 41415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regRowid); 41425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 41435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeCurrentAddr(v)+2, r, iSet); 41445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); 41465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The pSubWInfo->untestedTerms flag means that this OR term 41485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** contained one or more AND term from a notReady table. The 41495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** terms from the notReady table could not be tested and will 41505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** need to be tested later. 41515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 41525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pSubWInfo->untestedTerms ) untestedTerms = 1; 41535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Finish the loop through table entries that match term pOrTerm. */ 41555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3WhereEnd(pSubWInfo); 41565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v)); 41605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk); 41615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeResolveLabel(v, iLoopBody); 41625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pWInfo->nLevel>1 ) sqlite3StackFree(pParse->db, pOrTab); 41645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !untestedTerms ) disableTerm(pLevel, pTerm); 41655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else 41665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_OR_OPTIMIZATION */ 41675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 41695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Case 5: There is no usable index. We must do a complete 41705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** scan of the entire table. 41715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 41725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const u8 aStep[] = { OP_Next, OP_Prev }; 41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const u8 aStart[] = { OP_Rewind, OP_Last }; 41745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( bRev==0 || bRev==1 ); 41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( omitTable==0 ); 41765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->op = aStep[bRev]; 41775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->p1 = iCur; 41785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); 41795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; 41805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notReady &= ~getMask(pWC->pMaskSet, iCur); 41825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Insert code to test every subexpression that can be completely 41845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** computed using the current set of tables. 41855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 41865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through 41875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the use of indices become tests that are evaluated against each row of 41885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the relevant input tables. 41895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 41905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ 41915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pE; 41925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */ 41935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTerm->wtFlags & TERM_CODED ); 41945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; 41955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pTerm->prereqAll & notReady)!=0 ){ 41965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pWInfo->untestedTerms==0 41975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ); 41985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo->untestedTerms = 1; 41995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 42005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pE = pTerm->pExpr; 42025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pE!=0 ); 42035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){ 42045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 42055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); 42075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->wtFlags |= TERM_CODED; 42085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* For a LEFT OUTER JOIN, generate code that will record the fact that 42115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** at least one row of the right table has matched the left table. 42125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 42135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->iLeftJoin ){ 42145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); 42155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); 42165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VdbeComment((v, "record LEFT JOIN hit")); 42175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCacheClear(pParse); 42185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){ 42195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */ 42205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTerm->wtFlags & TERM_CODED ); 42215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; 42225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pTerm->prereqAll & notReady)!=0 ){ 42235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pWInfo->untestedTerms ); 42245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 42255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pTerm->pExpr ); 42275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); 42285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTerm->wtFlags |= TERM_CODED; 42295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ReleaseTempReg(pParse, iReleaseReg); 42325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return notReady; 42345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 42355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(SQLITE_TEST) 42375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 42385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The following variable holds a text description of query plan generated 42395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** by the most recent call to sqlite3WhereBegin(). Each call to WhereBegin 42405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** overwrites the previous. This information is used for testing and 42415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** analysis only. 42425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 42435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char sqlite3_query_plan[BMS*2*40]; /* Text of the join */ 42445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int nQPlan = 0; /* Next free slow in _query_plan[] */ 42455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_TEST */ 42475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 42505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Free a WhereInfo structure 42515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 42525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ 42535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ALWAYS(pWInfo) ){ 42545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 42555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<pWInfo->nLevel; i++){ 42565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo; 42575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pInfo ){ 42585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* assert( pInfo->needToFreeIdxStr==0 || db->mallocFailed ); */ 42595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pInfo->needToFreeIdxStr ){ 42605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(pInfo->idxStr); 42615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(db, pInfo); 42635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pWInfo->a[i].plan.wsFlags & WHERE_TEMP_INDEX ){ 42655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *pIdx = pWInfo->a[i].plan.u.pIdx; 42665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pIdx ){ 42675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(db, pIdx->zColAff); 42685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(db, pIdx); 42695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereClauseClear(pWInfo->pWC); 42735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(db, pWInfo); 42745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 42765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 42795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate the beginning of the loop used for WHERE clause processing. 42805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The return value is a pointer to an opaque structure that contains 42815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** information needed to terminate the loop. Later, the calling routine 42825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** should invoke sqlite3WhereEnd() with the return value of this function 42835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in order to complete the WHERE clause processing. 42845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 42855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If an error occurs, this routine returns NULL. 42865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 42875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The basic idea is to do a nested loop, one loop for each table in 42885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the FROM clause of a select. (INSERT and UPDATE statements are the 42895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** same as a SELECT with only a single table in the FROM clause.) For 42905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** example, if the SQL is this: 42915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 42925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SELECT * FROM t1, t2, t3 WHERE ...; 42935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 42945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Then the code generated is conceptually like the following: 42955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 42965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** foreach row1 in t1 do \ Code generated 42975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** foreach row2 in t2 do |-- by sqlite3WhereBegin() 42985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** foreach row3 in t3 do / 42995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ... 43005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** end \ Code generated 43015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** end |-- by sqlite3WhereEnd() 43025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** end / 43035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 43045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Note that the loops might not be nested in the order in which they 43055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** appear in the FROM clause if a different order is better able to make 43065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** use of indices. Note also that when the IN operator appears in 43075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the WHERE clause, it might result in additional nested loops for 43085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** scanning through all values on the right-hand side of the IN. 43095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 43105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** There are Btree cursors associated with each table. t1 uses cursor 43115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** number pTabList->a[0].iCursor. t2 uses the cursor pTabList->a[1].iCursor. 43125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** And so forth. This routine generates code to open those VDBE cursors 43135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and sqlite3WhereEnd() generates the code to close them. 43145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 43155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The code that sqlite3WhereBegin() generates leaves the cursors named 43165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in pTabList pointing at their appropriate entries. The [...] code 43175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** can use OP_Column and OP_Rowid opcodes on these cursors to extract 43185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** data from the various tables of the loop. 43195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 43205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the WHERE clause is empty, the foreach loops must each scan their 43215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** entire tables. Thus a three-way join is an O(N^3) operation. But if 43225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the tables have indices and there are terms in the WHERE clause that 43235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** refer to those indices, a complete table scan can be avoided and the 43245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** code will run much faster. Most of the work of this routine is checking 43255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to see if there are indices that can be used to speed up the loop. 43265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 43275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Terms of the WHERE clause are also used to limit which rows actually 43285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** make it to the "..." in the middle of the loop. After each "foreach", 43295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** terms of the WHERE clause that use only terms in that loop and outer 43305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** loops are evaluated and if false a jump is made around all subsequent 43315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** inner loops (or around the "..." if the test occurs within the inner- 43325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** most loop) 43335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 43345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** OUTER JOINS 43355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 43365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** An outer join of tables t1 and t2 is conceptally coded as follows: 43375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 43385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** foreach row1 in t1 do 43395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** flag = 0 43405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** foreach row2 in t2 do 43415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** start: 43425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ... 43435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** flag = 1 43445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** end 43455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** if flag==0 then 43465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** move the row2 cursor to a null row 43475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** goto start 43485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** fi 43495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** end 43505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 43515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ORDER BY CLAUSE PROCESSING 43525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 43535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** *ppOrderBy is a pointer to the ORDER BY clause of a SELECT statement, 43545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** if there is one. If there is no ORDER BY clause or if this routine 43555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is called from an UPDATE or DELETE statement, then ppOrderBy is NULL. 43565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 43575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If an index can be used so that the natural output order of the table 43585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** scan is correct for the ORDER BY clause, then that index is used and 43595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** *ppOrderBy is set to NULL. This is an optimization that prevents an 43605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** unnecessary sort of the result set if an index appropriate for the 43615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ORDER BY clause already exists. 43625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 43635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the where clause loops cannot be arranged to provide the correct 43645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** output order, then the *ppOrderBy is unchanged. 43655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 43665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WhereInfo *sqlite3WhereBegin( 43675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse, /* The parser context */ 43685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SrcList *pTabList, /* A list of all tables to be scanned */ 43695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expr *pWhere, /* The WHERE clause */ 43705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */ 43715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u16 wctrlFlags /* One of the WHERE_* flags defined in sqliteInt.h */ 43725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 43735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; /* Loop counter */ 43745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ 43755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nTabList; /* Number of elements in pTabList */ 43765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereInfo *pWInfo; /* Will become the return value of this function */ 43775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vdbe *v = pParse->pVdbe; /* The virtual database engine */ 43785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notReady; /* Cursors that are not yet positioned */ 43795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereMaskSet *pMaskSet; /* The expression mask set */ 43805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereClause *pWC; /* Decomposition of the WHERE clause */ 43815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SrcList_item *pTabItem; /* A single entry from pTabList */ 43825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereLevel *pLevel; /* A single level in the pWInfo list */ 43835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iFrom; /* First unused FROM clause element */ 43845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int andFlags; /* AND-ed combination of all pWC->a[].wtFlags */ 43855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db; /* Database connection */ 43865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The number of tables in the FROM clause is limited by the number of 43885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** bits in a Bitmask 43895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 43905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTabList->nSrc==BMS ); 43915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTabList->nSrc>BMS ){ 43925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS); 43935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 43945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This function normally generates a nested loop for all tables in 43975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** pTabList. But if the WHERE_ONETABLE_ONLY flag is set, then we should 43985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** only generate code for the first table in pTabList and assume that 43995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** any cursors associated with subsequent tables are uninitialized. 44005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 44015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nTabList = (wctrlFlags & WHERE_ONETABLE_ONLY) ? 1 : pTabList->nSrc; 44025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Allocate and initialize the WhereInfo structure that will become the 44045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** return value. A single allocation is used to store the WhereInfo 44055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** struct, the contents of WhereInfo.a[], the WhereClause structure 44065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte 44075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** field (type Bitmask) it must be aligned on an 8-byte boundary on 44085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** some architectures. Hence the ROUND8() below. 44095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 44105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db = pParse->db; 44115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); 44125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo = sqlite3DbMallocZero(db, 44135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nByteWInfo + 44145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(WhereClause) + 44155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(WhereMaskSet) 44165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 44175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( db->mallocFailed ){ 44185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(db, pWInfo); 44195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo = 0; 44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto whereBeginError; 44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo->nLevel = nTabList; 44235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo->pParse = pParse; 44245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo->pTabList = pTabList; 44255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo->iBreak = sqlite3VdbeMakeLabel(v); 44265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo->pWC = pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo]; 44275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo->wctrlFlags = wctrlFlags; 44285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo->savedNQueryLoop = pParse->nQueryLoop; 44295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pMaskSet = (WhereMaskSet*)&pWC[1]; 44305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Split the WHERE clause into separate subexpressions where each 44325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** subexpression is separated by an AND operator. 44335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 44345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initMaskSet(pMaskSet); 44355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereClauseInit(pWC, pParse, pMaskSet); 44365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCodeConstants(pParse, pWhere); 44375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereSplit(pWC, pWhere, TK_AND); /* IMP: R-15842-53296 */ 44385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Special case: a WHERE clause that is constant. Evaluate the 44405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** expression and either jump over all of the code or fall thru. 44415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 44425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pWhere && (nTabList==0 || sqlite3ExprIsConstantNotJoin(pWhere)) ){ 44435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, SQLITE_JUMPIFNULL); 44445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWhere = 0; 44455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Assign a bit from the bitmask to every term in the FROM clause. 44485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 44495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** When assigning bitmask values to FROM clause cursors, it must be 44505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the case that if X is the bitmask for the N-th FROM clause term then 44515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the bitmask for all FROM clause terms to the left of the N-th term 44525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is (X-1). An expression from the ON clause of a LEFT JOIN can use 44535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** its Expr.iRightJoinTable value to find the bitmask of the right table 44545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** of the join. Subtracting one from the right table bitmask gives a 44555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** bitmask for all tables to the left of the join. Knowing the bitmask 44565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** for all tables to the left of a left join is important. Ticket #3015. 44575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 44585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Configure the WhereClause.vmask variable so that bits that correspond 44595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** to virtual table cursors are set. This is used to selectively disable 44605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the OR-to-IN transformation in exprAnalyzeOrTerm(). It is not helpful 44615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** with virtual tables. 44625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 44635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Note that bitmasks are created for all pTabList->nSrc tables in 44645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** pTabList, not just the first nTabList tables. nTabList is normally 44655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** equal to pTabList->nSrc but might be shortened to 1 if the 44665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** WHERE_ONETABLE_ONLY flag is set. 44675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 44685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pWC->vmask==0 && pMaskSet->n==0 ); 44695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<pTabList->nSrc; i++){ 44705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) createMask(pMaskSet, pTabList->a[i].iCursor); 44715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE 44725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( ALWAYS(pTabList->a[i].pTab) && IsVirtual(pTabList->a[i].pTab) ){ 44735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWC->vmask |= ((Bitmask)1 << i); 44745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 44765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG 44785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 44795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask toTheLeft = 0; 44805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<pTabList->nSrc; i++){ 44815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask m = getMask(pMaskSet, pTabList->a[i].iCursor); 44825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( (m-1)==toTheLeft ); 44835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) toTheLeft |= m; 44845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 44875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Analyze all of the subexpressions. Note that exprAnalyze() might 44895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** add new virtual terms onto the end of the WHERE clause. We do not 44905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** want to analyze these virtual terms, so start analyzing at the end 44915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** and work forward so that the added virtual terms are never processed. 44925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 44935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exprAnalyzeAll(pTabList, pWC); 44945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( db->mallocFailed ){ 44955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto whereBeginError; 44965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Chose the best index to use for each table in the FROM clause. 44995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 45005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** This loop fills in the following fields: 45015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 45025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** pWInfo->a[].pIdx The index to use for this level of the loop. 45035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** pWInfo->a[].wsFlags WHERE_xxx flags associated with pIdx 45045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** pWInfo->a[].nEq The number of == and IN constraints 45055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** pWInfo->a[].iFrom Which term of the FROM clause is being coded 45065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** pWInfo->a[].iTabCur The VDBE cursor for the database table 45075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** pWInfo->a[].iIdxCur The VDBE cursor for the index 45085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** pWInfo->a[].pTerm When wsFlags==WO_OR, the OR-clause term 45095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 45105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** This loop also figures out the nesting order of tables in the FROM 45115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** clause. 45125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 45135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notReady = ~(Bitmask)0; 45145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) andFlags = ~0; 45155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("*** Optimizer Start ***\n")); 45165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=iFrom=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){ 45175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereCost bestPlan; /* Most efficient plan seen so far */ 45185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *pIdx; /* Index for FROM table at pTabItem */ 45195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; /* For looping over FROM tables */ 45205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bestJ = -1; /* The value of j */ 45215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask m; /* Bitmask value for j or bestJ */ 45225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isOptimal; /* Iterator for optimal/non-optimal search */ 45235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nUnconstrained; /* Number tables without INDEXED BY */ 45245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask notIndexed; /* Mask of tables that cannot use an index */ 45255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&bestPlan, 0, sizeof(bestPlan)); 45275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bestPlan.rCost = SQLITE_BIG_DBL; 45285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("*** Begin search for loop %d ***\n", i)); 45295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Loop through the remaining entries in the FROM clause to find the 45315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** next nested loop. The loop tests all FROM clause entries 45325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** either once or twice. 45335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 45345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The first test is always performed if there are two or more entries 45355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** remaining and never performed if there is only one FROM clause entry 45365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** to choose from. The first test looks for an "optimal" scan. In 45375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** this context an optimal scan is one that uses the same strategy 45385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** for the given FROM clause entry as would be selected if the entry 45395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** were used as the innermost nested loop. In other words, a table 45405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is chosen such that the cost of running that table cannot be reduced 45415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** by waiting for other tables to run first. This "optimal" test works 45425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** by first assuming that the FROM clause is on the inner loop and finding 45435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** its query plan, then checking to see if that query plan uses any 45445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** other FROM clause terms that are notReady. If no notReady terms are 45455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** used then the "optimal" query plan works. 45465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 45475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Note that the WhereCost.nRow parameter for an optimal scan might 45485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** not be as small as it would be if the table really were the innermost 45495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** join. The nRow value can be reduced by WHERE clause constraints 45505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** that do not use indices. But this nRow reduction only happens if the 45515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** table really is the innermost join. 45525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 45535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The second loop iteration is only performed if no optimal scan 45545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** strategies were found by the first iteration. This second iteration 45555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is used to search for the lowest cost scan overall. 45565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 45575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Previous versions of SQLite performed only the second iteration - 45585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the next outermost loop was always that with the lowest overall 45595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** cost. However, this meant that SQLite could select the wrong plan 45605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** for scripts such as the following: 45615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 45625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** CREATE TABLE t1(a, b); 45635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** CREATE TABLE t2(c, d); 45645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** SELECT * FROM t2, t1 WHERE t2.rowid = t1.a; 45655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 45665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The best strategy is to iterate through table t1 first. However it 45675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is not possible to determine this with a simple greedy algorithm. 45685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Since the cost of a linear scan through table t2 is the same 45695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** as the cost of a linear scan through table t1, a simple greedy 45705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** algorithm may choose to use t2 for the outer loop, which is a much 45715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** costlier approach. 45725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 45735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nUnconstrained = 0; 45745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notIndexed = 0; 45755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(isOptimal=(iFrom<nTabList-1); isOptimal>=0 && bestJ<0; isOptimal--){ 45765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask mask; /* Mask of tables not yet ready */ 45775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=iFrom, pTabItem=&pTabList->a[j]; j<nTabList; j++, pTabItem++){ 45785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int doNotReorder; /* True if this table should not be reordered */ 45795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereCost sCost; /* Cost information from best[Virtual]Index() */ 45805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprList *pOrderBy; /* ORDER BY clause for index to optimize */ 45815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doNotReorder = (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0; 45835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j!=iFrom && doNotReorder ) break; 45845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m = getMask(pMaskSet, pTabItem->iCursor); 45855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (m & notReady)==0 ){ 45865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( j==iFrom ) iFrom++; 45875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 45885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask = (isOptimal ? m : notReady); 45905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0); 45915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pTabItem->pIndex==0 ) nUnconstrained++; 45925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("=== trying table %d with isOptimal=%d ===\n", 45945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j, isOptimal)); 45955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pTabItem->pTab ); 45965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE 45975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( IsVirtual(pTabItem->pTab) ){ 45985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_index_info **pp = &pWInfo->a[j].pIdxInfo; 45995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bestVirtualIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy, 46005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &sCost, pp); 46015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else 46025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 46035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 46045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bestBtreeIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy, 46055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &sCost); 46065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( isOptimal || (sCost.used¬Ready)==0 ); 46085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If an INDEXED BY clause is present, then the plan must use that 46105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** index if it uses any index at all */ 46115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pTabItem->pIndex==0 46125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 46135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || sCost.plan.u.pIdx==pTabItem->pIndex ); 46145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( isOptimal && (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){ 46165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notIndexed |= m; 46175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Conditions under which this table becomes the best so far: 46205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 46215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** (1) The table must not depend on other tables that have not 46225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** yet run. 46235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 46245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** (2) A full-table-scan plan cannot supercede indexed plan unless 46255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the full-table-scan is an "optimal" plan as defined above. 46265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 46275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** (3) All tables have an INDEXED BY clause or this table lacks an 46285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** INDEXED BY clause or this table uses the specific 46295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** index specified by its INDEXED BY clause. This rule ensures 46305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** that a best-so-far is always selected even if an impossible 46315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** combination of INDEXED BY clauses are given. The error 46325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** will be detected and relayed back to the application later. 46335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The NEVER() comes about because rule (2) above prevents 46345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** An indexable full-table-scan from reaching rule (3). 46355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 46365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** (4) The plan cost must be lower than prior plans or else the 46375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** cost must be the same and the number of rows must be lower. 46385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 46395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (sCost.used¬Ready)==0 /* (1) */ 46405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (bestJ<0 || (notIndexed&m)!=0 /* (2) */ 46415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 46425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0) 46435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (nUnconstrained==0 || pTabItem->pIndex==0 /* (3) */ 46445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || NEVER((sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)) 46455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (bestJ<0 || sCost.rCost<bestPlan.rCost /* (4) */ 46465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || (sCost.rCost<=bestPlan.rCost 46475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && sCost.plan.nRow<bestPlan.plan.nRow)) 46485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 46495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("=== table %d is best so far" 46505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " with cost=%g and nRow=%g\n", 46515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j, sCost.rCost, sCost.plan.nRow)); 46525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bestPlan = sCost; 46535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bestJ = j; 46545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( doNotReorder ) break; 46565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( bestJ>=0 ); 46595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) ); 46605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("*** Optimizer selects table %d for loop %d" 46615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " with cost=%g and nRow=%g\n", 46625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow)); 46635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){ 46645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ppOrderBy = 0; 46655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) andFlags &= bestPlan.plan.wsFlags; 46675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->plan = bestPlan.plan; 46685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( bestPlan.plan.wsFlags & WHERE_INDEXED ); 46695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( bestPlan.plan.wsFlags & WHERE_TEMP_INDEX ); 46705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( bestPlan.plan.wsFlags & (WHERE_INDEXED|WHERE_TEMP_INDEX) ){ 46715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->iIdxCur = pParse->nTab++; 46725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 46735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->iIdxCur = -1; 46745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notReady &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor); 46765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->iFrom = (u8)bestJ; 46775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( bestPlan.plan.nRow>=(double)1 ){ 46785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pParse->nQueryLoop *= bestPlan.plan.nRow; 46795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check that if the table scanned by this loop iteration had an 46825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** INDEXED BY clause attached to it, that the named index is being 46835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** used for the scan. If not, then query compilation has failed. 46845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Return an error. 46855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 46865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdx = pTabList->a[bestJ].pIndex; 46875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pIdx ){ 46885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (bestPlan.plan.wsFlags & WHERE_INDEXED)==0 ){ 46895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ErrorMsg(pParse, "cannot use index: %s", pIdx->zName); 46905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto whereBeginError; 46915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 46925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If an INDEXED BY clause is used, the bestIndex() function is 46935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** guaranteed to find the index specified in the INDEXED BY clause 46945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** if it find an index at all. */ 46955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( bestPlan.plan.u.pIdx==pIdx ); 46965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERETRACE(("*** Optimizer Finished ***\n")); 47005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pParse->nErr || db->mallocFailed ){ 47015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto whereBeginError; 47025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the total query only selects a single row, then the ORDER BY 47055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** clause is irrelevant. 47065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 47075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (andFlags & WHERE_UNIQUE)!=0 && ppOrderBy ){ 47085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ppOrderBy = 0; 47095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the caller is an UPDATE or DELETE statement that is requesting 47125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** to use a one-pass algorithm, determine if this is appropriate. 47135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** The one-pass algorithm only works if the WHERE clause constraints 47145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the statement to update a single row. 47155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 47165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 ); 47175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 && (andFlags & WHERE_UNIQUE)!=0 ){ 47185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo->okOnePass = 1; 47195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo->a[0].plan.wsFlags &= ~WHERE_IDX_ONLY; 47205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Open all tables in the pTabList and any indices selected for 47235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** searching those tables. 47245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 47255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */ 47265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notReady = ~(Bitmask)0; 47275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo->nRowOut = (double)1; 47285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){ 47295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Table *pTab; /* Table to open */ 47305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iDb; /* Index of database containing table/index */ 47315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTabItem = &pTabList->a[pLevel->iFrom]; 47335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTab = pTabItem->pTab; 47345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel->iTabCur = pTabItem->iCursor; 47355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo->nRowOut *= pLevel->plan.nRow; 47365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iDb = sqlite3SchemaToIndex(db, pTab->pSchema); 47375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){ 47385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Do nothing */ 47395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else 47405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE 47415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){ 47425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); 47435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iCur = pTabItem->iCursor; 47445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB); 47455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else 47465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 47475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0 47485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (wctrlFlags & WHERE_OMIT_OPEN)==0 ){ 47495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead; 47505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op); 47515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTab->nCol==BMS-1 ); 47525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pTab->nCol==BMS ); 47535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !pWInfo->okOnePass && pTab->nCol<BMS ){ 47545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bitmask b = pTabItem->colUsed; 47555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int n = 0; 47565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(; b; b=b>>1, n++){} 47575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1, 47585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SQLITE_INT_TO_PTR(n), P4_INT32); 47595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( n<=pTab->nCol ); 47605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 47625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); 47635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_AUTOMATIC_INDEX 47655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX)!=0 ){ 47665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) constructAutomaticIndex(pParse, pWC, pTabItem, notReady, pLevel); 47675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else 47685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 47695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ 47705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *pIx = pLevel->plan.u.pIdx; 47715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx); 47725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iIdxCur = pLevel->iIdxCur; 47735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pIx->pSchema==pTab->pSchema ); 47745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( iIdxCur>=0 ); 47755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIx->tnum, iDb, 47765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (char*)pKey, P4_KEYINFO_HANDOFF); 47775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VdbeComment((v, "%s", pIx->zName)); 47785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3CodeVerifySchema(pParse, iDb); 47805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notReady &= ~getMask(pWC->pMaskSet, pTabItem->iCursor); 47815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo->iTop = sqlite3VdbeCurrentAddr(v); 47835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( db->mallocFailed ) goto whereBeginError; 47845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate the code to do the search. Each iteration of the for 47865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** loop below generates code for a single nested loop of the VM 47875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** program. 47885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 47895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notReady = ~(Bitmask)0; 47905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<nTabList; i++){ 47915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel = &pWInfo->a[i]; 47925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags); 47935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady); 47945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pWInfo->iContinue = pLevel->addrCont; 47955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_TEST /* For testing and debugging use only */ 47985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Record in the query plan information about the current table 47995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** and the index used to access it (if any). If the table itself 48005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** is not used, its name is just '{}'. If no index is used 48015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the index is listed as "{}". If the primary key is used the 48025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** index name is '*'. 48035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 48045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<nTabList; i++){ 48055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *z; 48065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int n; 48075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel = &pWInfo->a[i]; 48085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTabItem = &pTabList->a[pLevel->iFrom]; 48095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z = pTabItem->zAlias; 48105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( z==0 ) z = pTabItem->pTab->zName; 48115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = sqlite3Strlen30(z); 48125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( n+nQPlan < sizeof(sqlite3_query_plan)-10 ){ 48135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->plan.wsFlags & WHERE_IDX_ONLY ){ 48145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&sqlite3_query_plan[nQPlan], "{}", 2); 48155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nQPlan += 2; 48165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 48175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&sqlite3_query_plan[nQPlan], z, n); 48185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nQPlan += n; 48195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_query_plan[nQPlan++] = ' '; 48215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pLevel->plan.wsFlags & WHERE_ROWID_EQ ); 48235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testcase( pLevel->plan.wsFlags & WHERE_ROWID_RANGE ); 48245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->plan.wsFlags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ 48255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&sqlite3_query_plan[nQPlan], "* ", 2); 48265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nQPlan += 2; 48275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){ 48285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = sqlite3Strlen30(pLevel->plan.u.pIdx->zName); 48295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( n+nQPlan < sizeof(sqlite3_query_plan)-2 ){ 48305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&sqlite3_query_plan[nQPlan], pLevel->plan.u.pIdx->zName, n); 48315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nQPlan += n; 48325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_query_plan[nQPlan++] = ' '; 48335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 48355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&sqlite3_query_plan[nQPlan], "{} ", 3); 48365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nQPlan += 3; 48375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( nQPlan>0 && sqlite3_query_plan[nQPlan-1]==' ' ){ 48405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_query_plan[--nQPlan] = 0; 48415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_query_plan[nQPlan] = 0; 48435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nQPlan = 0; 48445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_TEST // Testing and debugging use only */ 48455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Record the continuation address in the WhereInfo structure. Then 48475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** clean up and return. 48485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 48495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pWInfo; 48505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Jump here if malloc fails */ 48525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)whereBeginError: 48535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pWInfo ){ 48545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pParse->nQueryLoop = pWInfo->savedNQueryLoop; 48555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereInfoFree(db, pWInfo); 48565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 48585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 48595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 48615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate the end of the WHERE loop. See comments on 48625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3WhereBegin() for additional information. 48635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 48645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3WhereEnd(WhereInfo *pWInfo){ 48655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parse *pParse = pWInfo->pParse; 48665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vdbe *v = pParse->pVdbe; 48675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 48685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WhereLevel *pLevel; 48695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SrcList *pTabList = pWInfo->pTabList; 48705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db = pParse->db; 48715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate loop termination code. 48735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 48745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3ExprCacheClear(pParse); 48755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=pWInfo->nLevel-1; i>=0; i--){ 48765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pLevel = &pWInfo->a[i]; 48775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeResolveLabel(v, pLevel->addrCont); 48785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->op!=OP_Noop ){ 48795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2); 48805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeChangeP5(v, pLevel->p5); 48815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->plan.wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){ 48835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct InLoop *pIn; 48845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 48855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeResolveLabel(v, pLevel->addrNxt); 48865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ 48875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeJumpHere(v, pIn->addrInTop+1); 48885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Next, pIn->iCur, pIn->addrInTop); 48895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeJumpHere(v, pIn->addrInTop-1); 48905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3DbFree(db, pLevel->u.in.aInLoop); 48925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeResolveLabel(v, pLevel->addrBrk); 48945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->iLeftJoin ){ 48955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int addr; 48965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); 48975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0 48985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ); 48995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0 ){ 49005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor); 49015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->iIdxCur>=0 ){ 49035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); 49045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pLevel->op==OP_Return ){ 49065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst); 49075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 49085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrFirst); 49095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeJumpHere(v, addr); 49115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The "break" point is here, just past the end of the outer loop. 49155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Set it. 49165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 49175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeResolveLabel(v, pWInfo->iBreak); 49185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Close all of the cursors that were opened by sqlite3WhereBegin. 49205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 49215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pWInfo->nLevel==1 || pWInfo->nLevel==pTabList->nSrc ); 49225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){ 49235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; 49245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Table *pTab = pTabItem->pTab; 49255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pTab!=0 ); 49265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pTab->tabFlags & TF_Ephemeral)==0 49275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && pTab->pSelect==0 49285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (pWInfo->wctrlFlags & WHERE_OMIT_CLOSE)==0 49295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 49305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ws = pLevel->plan.wsFlags; 49315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){ 49325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); 49335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (ws & WHERE_INDEXED)!=0 && (ws & WHERE_TEMP_INDEX)==0 ){ 49355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); 49365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If this scan uses an index, make code substitutions to read data 49405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** from the index in preference to the table. Sometimes, this means 49415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** the table need never be read from. This is a performance boost, 49425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** as the vdbe level waits until the table is read before actually 49435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** seeking the table cursor to the record corresponding to the current 49445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** position in the index. 49455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 49465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Calls to the code generator in between sqlite3WhereBegin and 49475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** sqlite3WhereEnd will have created code that references the table 49485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** directly. This loop scans all that code looking for opcodes 49495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** that reference the table and converts them into opcodes that 49505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** reference the index. 49515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 49525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 && !db->mallocFailed){ 49535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int k, j, last; 49545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VdbeOp *pOp; 49555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Index *pIdx = pLevel->plan.u.pIdx; 49565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( pIdx!=0 ); 49585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOp = sqlite3VdbeGetOp(v, pWInfo->iTop); 49595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last = sqlite3VdbeCurrentAddr(v); 49605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(k=pWInfo->iTop; k<last; k++, pOp++){ 49615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOp->p1!=pLevel->iTabCur ) continue; 49625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOp->opcode==OP_Column ){ 49635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(j=0; j<pIdx->nColumn; j++){ 49645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pOp->p2==pIdx->aiColumn[j] ){ 49655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOp->p2 = j; 49665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOp->p1 = pLevel->iIdxCur; 49675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0 49715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || j<pIdx->nColumn ); 49725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( pOp->opcode==OP_Rowid ){ 49735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOp->p1 = pLevel->iIdxCur; 49745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pOp->opcode = OP_IdxRowid; 49755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Final cleanup 49815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 49825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pParse->nQueryLoop = pWInfo->savedNQueryLoop; 49835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) whereInfoFree(db, pWInfo); 49845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 49855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4986