-C Update\smemsubsys1.test\sto\saccount\sfor\sthe\srecently\sincreased\ssize\sof\sthe\sMemPage\sstructure\sin\sbtreeInt.h.
-D 2011-11-16T08:18:20.698
+C Where\spossible,\stake\sadvantage\sof\sthe\srowid\sat\sthe\send\sof\sindex\srecords\sto\soptimize\srange\sconstraints\s(<,\s>,\s<=,\s>=)\son\sthe\srowid\scolumn.
+D 2011-11-16T15:27:09.116
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
-F src/insert.c 9794a963911da8157ad0dc39726c9c695b1c4692
+F src/insert.c 8f283d6734dd837ed7531b26d7622fda70874390
F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84
F src/util.c 01238e2b0f24a14779181dbf991fe02620a80e31
F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa
-F src/vdbe.c 326994a64a9a08853122200dc9f62cb96b8f0831
+F src/vdbe.c a7ab9993ec5a4d9479dc99671faec061fbf9b889
F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755
F src/vdbeInt.h 9498fc98a2c9e349a4ef13455ff5a3e898f40176
F src/vdbeapi.c 4dbba7f94f127f6ea8d2d0505ee1f98e5ffbf546
-F src/vdbeaux.c a950e34449a508d48d90475acc287943a4094f3a
+F src/vdbeaux.c 17bee21d513b8567f2e010aea287e81e9e6e273f
F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb
F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56
F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790
F src/wal.c 5fe1ba55b8fab9d3936bc9093af61ab9f1c580a1
F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
-F src/where.c 7c85f4c93058e27100d404f0777aaeb0d1b296ae
+F src/where.c f73752ca85c0ed221753fda98aeaf6b9d4616e0e
F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/where9.test bed66dcfc69a54a99661c0c9906189cb5e58f4e2
F test/whereA.test 24c234263c8fe358f079d5e57d884fb569d2da0a
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
+F test/whereC.test 13ff5ec0dba407c0e0c075980c75b3275a6774e5
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P ebf6eb6ed756c0a3158b4cb5fb4b460c79d93c29
-R caea05edce79a54f0d9a19e01ae7581d
+P 4fb3ca756a3a7c66baa4745a9b2c1e246a67c699
+R 131e1406052949b0c9af0dcdeb54bce6
U dan
-Z 63891b2b7447d3ac397ed0d8ca697472
+Z 4ed1ee25329fe5dbd728820234ee8619
-4fb3ca756a3a7c66baa4745a9b2c1e246a67c699
\ No newline at end of file
+3b58f5f06648205a47e5cace0201269c406e476a
\ No newline at end of file
** 'd' INTEGER
** 'e' REAL
**
-** An extra 'b' is appended to the end of the string to cover the
+** An extra 'd' is appended to the end of the string to cover the
** rowid that appears as the last column in every index.
**
** Memory for the buffer containing the column index affinity string
for(n=0; n<pIdx->nColumn; n++){
pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;
}
- pIdx->zColAff[n++] = SQLITE_AFF_NONE;
+ pIdx->zColAff[n++] = SQLITE_AFF_INTEGER;
pIdx->zColAff[n] = 0;
}
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p4.i;
if( pOp->p5 ){
- r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID;
+ r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
}else{
- r.flags = UNPACKED_IGNORE_ROWID;
+ r.flags = UNPACKED_PREFIX_MATCH;
}
r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
if( rc ){
return rc;
}
- assert( pUnpacked->flags & UNPACKED_IGNORE_ROWID );
+ assert( pUnpacked->flags & UNPACKED_PREFIX_SEARCH );
*res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked);
sqlite3VdbeMemRelease(&m);
return SQLITE_OK;
&& pTerm->u.leftColumn==iColumn
&& (pTerm->eOperator & op)!=0
){
- if( pIdx && pTerm->eOperator!=WO_ISNULL ){
+ if( iColumn>=0 && pIdx && pTerm->eOperator!=WO_ISNULL ){
Expr *pX = pTerm->pExpr;
CollSeq *pColl;
char idxaff;
#endif
used |= pTerm->prereqRight;
}
-
- /* Determine the value of rangeDiv */
- if( nEq<pProbe->nColumn && pProbe->bUnordered==0 ){
- int j = pProbe->aiColumn[nEq];
+
+ /* If the index being considered is UNIQUE, and there is an equality
+ ** constraint for all columns in the index, then this search will find
+ ** at most a single row. In this case set the WHERE_UNIQUE flag to
+ ** indicate this to the caller.
+ **
+ ** Otherwise, if the search may find more than one row, test to see if
+ ** there is a range constraint on indexed column (nEq+1) that can be
+ ** optimized using the index.
+ */
+ if( nEq==pProbe->nColumn && pProbe->onError!=OE_None ){
+ testcase( wsFlags & WHERE_COLUMN_IN );
+ testcase( wsFlags & WHERE_COLUMN_NULL );
+ if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
+ wsFlags |= WHERE_UNIQUE;
+ }
+ }else if( pProbe->bUnordered==0 ){
+ int j = (nEq==pProbe->nColumn ? -1 : pProbe->aiColumn[nEq]);
if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx);
}
wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE);
}
- }else if( pProbe->onError!=OE_None ){
- testcase( wsFlags & WHERE_COLUMN_IN );
- testcase( wsFlags & WHERE_COLUMN_NULL );
- if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
- wsFlags |= WHERE_UNIQUE;
- }
}
/* If there is an ORDER BY clause and the index being considered will
j = i;
if( pPlan->wsFlags&WHERE_BTM_LIMIT ){
- explainAppendTerm(&txt, i++, aCol[aiColumn[j]].zName, ">");
+ char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
+ explainAppendTerm(&txt, i++, z, ">");
}
if( pPlan->wsFlags&WHERE_TOP_LIMIT ){
- explainAppendTerm(&txt, i, aCol[aiColumn[j]].zName, "<");
+ char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
+ explainAppendTerm(&txt, i, z, "<");
}
sqlite3StrAccumAppend(&txt, ")", 1);
return sqlite3StrAccumFinish(&txt);
pIdx = pLevel->plan.u.pIdx;
iIdxCur = pLevel->iIdxCur;
- k = pIdx->aiColumn[nEq]; /* Column for inequality constraints */
+ k = (nEq==pIdx->nColumn ? -1 : pIdx->aiColumn[nEq]);
/* If this loop satisfies a sort order (pOrderBy) request that
** was passed to this function to implement a "SELECT min(x) ..."
** a forward order scan on a descending index, interchange the
** start and end terms (pRangeStart and pRangeEnd).
*/
- if( nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){
+ if( (nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
+ || (bRev && pIdx->nColumn==nEq)
+ ){
SWAP(WhereTerm *, pRangeEnd, pRangeStart);
}
--- /dev/null
+# 2011 November 16
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix whereC
+
+do_execsql_test 1.0 {
+ CREATE TABLE t1(i INTEGER PRIMARY KEY, a, b INTEGER);
+
+ INSERT INTO t1 VALUES(1, 1, 1);
+ INSERT INTO t1 VALUES(2, 1, 1);
+ INSERT INTO t1 VALUES(3, 1, 2);
+ INSERT INTO t1 VALUES(4, 1, 2);
+ INSERT INTO t1 VALUES(5, 1, 2);
+ INSERT INTO t1 VALUES(6, 1, 3);
+ INSERT INTO t1 VALUES(7, 1, 3);
+
+ INSERT INTO t1 VALUES(8, 2, 1);
+ INSERT INTO t1 VALUES(9, 2, 1);
+ INSERT INTO t1 VALUES(10, 2, 2);
+ INSERT INTO t1 VALUES(11, 2, 2);
+ INSERT INTO t1 VALUES(12, 2, 2);
+ INSERT INTO t1 VALUES(13, 2, 3);
+ INSERT INTO t1 VALUES(14, 2, 3);
+
+ INSERT INTO t1 VALUES(15, 2, 1);
+ INSERT INTO t1 VALUES(16, 2, 1);
+ INSERT INTO t1 VALUES(17, 2, 2);
+ INSERT INTO t1 VALUES(18, 2, 2);
+ INSERT INTO t1 VALUES(19, 2, 2);
+ INSERT INTO t1 VALUES(20, 2, 3);
+ INSERT INTO t1 VALUES(21, 2, 3);
+
+ CREATE INDEX i1 ON t1(a, b);
+}
+
+foreach {tn sql res} {
+ 1 "SELECT i FROM t1 WHERE a=1 AND b=2 AND i>3" {4 5}
+ 2 "SELECT i FROM t1 WHERE rowid='12'" {12}
+ 3 "SELECT i FROM t1 WHERE a=1 AND b='2'" {3 4 5}
+ 4 "SELECT i FROM t1 WHERE a=1 AND b='2' AND i>'3'" {4 5}
+ 5 "SELECT i FROM t1 WHERE a=1 AND b='2' AND i<5" {3 4}
+ 6 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i<12" {10 11}
+ 7 "SELECT i FROM t1 WHERE a IN(1, 2) AND b=2 AND i<11" {3 4 5 10}
+ 8 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i BETWEEN 10 AND 12" {10 11 12}
+ 9 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i BETWEEN 11 AND 12" {11 12}
+ 10 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i BETWEEN 10 AND 11" {10 11}
+ 11 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i BETWEEN 12 AND 10" {}
+ 12 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i<NULL" {}
+ 13 "SELECT i FROM t1 WHERE a=2 AND b=2 AND i>=NULL" {}
+ 14 "SELECT i FROM t1 WHERE a=1 AND b='2' AND i<4.5" {3 4}
+} {
+ do_execsql_test 1.$tn.1 $sql $res
+ do_execsql_test 1.$tn.2 "$sql ORDER BY i ASC" [lsort -integer -inc $res]
+ do_execsql_test 1.$tn.3 "$sql ORDER BY i DESC" [lsort -integer -dec $res]
+}
+
+
+finish_test
+