-C Add\ssome\ssupport\sfor\sOR\sterms\sto\ssqlite3_whereinfo_hook().
-D 2017-04-04T17:50:31.913
+C Changes\sto\sallow\sindexes\sto\sbe\srecommended\sfor\squeries\son\sSQL\sviews.
+D 2017-04-06T18:44:18.391
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c 2496d0cc6368dabe7ad2e4c7f5ed3ad9aa3b4d11cd90f33fa1d1ef72493f43aa
F src/shell.c e524688c2544167f835ba43e24309f8707ca60c8ab6eb5c263a12c8618a233b8
-F src/shell_indexes.c d40ea0a81112df7bdccd7232238bee0bbb39699085ea78cc08fd863bf052a63b
+F src/shell_indexes.c 1f5ab036ec189411aeea27e6e74ab0009d831764d5d8517455dcb6b6a734beb7
F src/sqlite.h.in ae5c9cbf2e77492c319fca08769575d9695e64718a16d32324944d24e291bcf7
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28
F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1
F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d
F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9
-F test/shell6.test 081067c1afcb38da50134ffd5ccc0a59ede14f41959486f733ffbba689c0ccfa
+F test/shell6.test f37998b26dfde19beaaf06a4cb60c476f66a7b54affff3870a2a011402c13efc
F test/shell7.test 07751911b294698e0c5df67bcbd29e7d2f0f2907
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P a54aef35da11f7508a8888a159372036a362fc52afa1df752dc835db334c4330
-R 51e547bc1c25ea79dd375d8f020224f3
+P 5cd070000da1d9e399090677b4db75dc5639c33211385d6eb84f14a4d0b617cd
+R aa13547c61fd31f43629472eaf9b4008
U dan
-Z fe378068686ea107c39185021a17b4ae
+Z 2f3b5e2a515dd18e4123d763066c9a33
/*
** A WHERE clause. Made up of IdxConstraint objects. Example WHERE clause:
**
-** a=? AND b=? AND ((c=? AND d=?) OR e=?) AND (f=? OR g=?) AND h>?
+** a=? AND b=? AND c=? AND d=? AND e>? AND f<?
**
-** The above is decomposed into 5 AND connected clauses. The first two are
+** The above is decomposed into 6 AND connected clauses. The first four are
** added to the IdxWhere.pEq linked list, the following two into
-** IdxWhere.pOr and the last into IdxWhere.pRange.
+** IdxWhere.pRange.
**
** IdxWhere.pEq and IdxWhere.pRange are simple linked lists of IdxConstraint
** objects linked by the IdxConstraint.pNext field.
-**
-** The list headed at IdxWhere.pOr and linked by IdxWhere.pNextOr contains
-** all "OR" terms that belong to the current WHERE clause. In the example
-** above, there are two OR terms:
-**
-** ((c=? AND d=?) OR e=?)
-** (f=? OR g=?)
-**
-** Within an OR term, the OR connected sub-expressions are termed siblings.
-** These are connected into a linked list by the pSibling pointers. Each OR
-** term above consists of two siblings.
-**
-** pOr -> (c=? AND d=?) -> pNextOr -> (f=?)
-** | |
-** pSibling pSibling
-** | |
-** V V
-** (e=?) (g=?)
-**
-** IdxWhere.pParent is only used while constructing a tree of IdxWhere
-** structures. It is NULL for the root IdxWhere. For all others, the parent
-** WHERE clause.
*/
struct IdxWhere {
IdxConstraint *pEq; /* List of == constraints */
IdxConstraint *pRange; /* List of < constraints */
- IdxWhere *pOr; /* List of OR constraints */
- IdxWhere *pNextOr; /* Next in OR constraints of same IdxWhere */
- IdxWhere *pSibling; /* Next branch in single OR constraint */
- IdxWhere *pParent; /* Parent object (or NULL) */
};
/*
*pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
}
-static char *idxQueryToList(
- sqlite3 *db,
- const char *zBind,
- int *pRc,
- char **pzErrmsg,
- const char *zSql
-){
- char *zRet = 0;
- if( *pRc==SQLITE_OK ){
- sqlite3_stmt *pStmt = 0;
- int rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_text(pStmt, 1, zBind, -1, SQLITE_TRANSIENT);
- while( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
- const char *z = (const char*)sqlite3_column_text(pStmt, 0);
- zRet = sqlite3_mprintf("%z%s%Q", zRet, zRet?", ":"", z);
- if( zRet==0 ){
- rc = SQLITE_NOMEM;
- }
- }
- rc = sqlite3_finalize(pStmt);
- }
-
- if( rc ){
- idxDatabaseError(db, pzErrmsg);
- sqlite3_free(zRet);
- zRet = 0;
- }
- *pRc = rc;
- }
-
- return zRet;
-}
-
static int idxPrepareStmt(
sqlite3 *db, /* Database handle to compile against */
sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */
rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTbl);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
- const char *zCol = sqlite3_column_text(p1, 1);
+ const char *zCol = (const char*)sqlite3_column_text(p1, 1);
nByte += 1 + strlen(zCol);
rc = sqlite3_table_column_metadata(
db, "main", zTbl, zCol, 0, &zCol, 0, 0, 0
nCol = 0;
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
- const char *zCol = sqlite3_column_text(p1, 1);
+ const char *zCol = (const char*)sqlite3_column_text(p1, 1);
int nCopy = strlen(zCol) + 1;
pNew->aCol[nCol].zName = pCsr;
pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5);
char **pzErrmsg /* OUT: Error message */
){
int rc = SQLITE_OK;
+ int rc2;
IdxScan *pIter;
- for(pIter=pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){
- rc = idxGetTableInfo(db, pIter, pzErrmsg);
+ sqlite3_stmt *pSql = 0;
- /* Test if table has already been created. If so, jump to the next
- ** iteration of the loop. */
- if( rc==SQLITE_OK ){
- sqlite3_stmt *pSql = 0;
- rc = idxPrintfPrepareStmt(dbm, &pSql, pzErrmsg,
- "SELECT 1 FROM sqlite_master WHERE tbl_name = %Q", pIter->zTable
- );
- if( rc==SQLITE_OK ){
- int bSkip = 0;
- if( sqlite3_step(pSql)==SQLITE_ROW ) bSkip = 1;
- rc = sqlite3_finalize(pSql);
- if( bSkip ) continue;
- }
- }
+ /* Copy the entire schema of database [db] into [dbm]. */
+ rc = idxPrintfPrepareStmt(db, &pSql, pzErrmsg,
+ "SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%%'"
+ );
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
+ const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
+ rc = sqlite3_exec(dbm, zSql, 0, 0, pzErrmsg);
+ }
+ rc2 = sqlite3_finalize(pSql);
+ if( rc==SQLITE_OK ) rc = rc2;
- if( rc==SQLITE_OK ){
- int rc2;
- sqlite3_stmt *pSql = 0;
- rc = idxPrintfPrepareStmt(db, &pSql, pzErrmsg,
- "SELECT sql FROM sqlite_master WHERE tbl_name = %Q", pIter->zTable
- );
- while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
- const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
- rc = sqlite3_exec(dbm, zSql, 0, 0, pzErrmsg);
- }
- rc2 = sqlite3_finalize(pSql);
- if( rc==SQLITE_OK ) rc = rc2;
- }
+ /* Load IdxTable objects */
+ for(pIter=pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){
+ rc = idxGetTableInfo(db, pIter, pzErrmsg);
}
return rc;
}
IdxContext*, i64, IdxScan*, IdxWhere*, IdxConstraint*, IdxConstraint*
);
-static int idxCreateForeachOr(
- IdxContext *pCtx,
- i64 mask, /* Consider only these constraints */
- IdxScan *pScan, /* Create indexes for this scan */
- IdxWhere *pWhere, /* Read constraints from here */
- IdxConstraint *pEq, /* == constraints for inclusion */
- IdxConstraint *pTail /* range/ORDER BY constraints for inclusion */
-){
- int rc = SQLITE_OK;
- IdxWhere *p1;
- IdxWhere *p2;
- for(p1=pWhere->pOr; p1 && rc==SQLITE_OK; p1=p1->pNextOr){
- rc = idxCreateFromWhere(pCtx, mask, pScan, p1, pEq, pTail);
- for(p2=p1->pSibling; p2 && rc==SQLITE_OK; p2=p2->pSibling){
- rc = idxCreateFromWhere(pCtx, mask, pScan, p2, pEq, pTail);
- }
- }
- return rc;
-}
-
/*
** Return true if list pList (linked by IdxConstraint.pLink) contains
** a constraint compatible with *p. Otherwise return false.
IdxConstraint *pEq, /* == constraints for inclusion */
IdxConstraint *pTail /* range/ORDER BY constraints for inclusion */
){
- sqlite3 *dbm = pCtx->dbm;
IdxConstraint *p1 = pEq;
IdxConstraint *pCon;
int rc;
/* Create an index using the == constraints collected above. And the
** range constraint/ORDER BY terms passed in by the caller, if any. */
rc = idxCreateFromCons(pCtx, pScan, p1, pTail);
- if( rc==SQLITE_OK ){
- rc = idxCreateForeachOr(pCtx, mask, pScan, pWhere, p1, pTail);
- }
/* If no range/ORDER BY passed by the caller, create a version of the
** index for each range constraint that matches the mask. */
&& idxFindConstraint(pTail, pCon)==0
){
rc = idxCreateFromCons(pCtx, pScan, p1, pCon);
- if( rc==SQLITE_OK ){
- rc = idxCreateForeachOr(pCtx, mask, pScan, pWhere, p1, pCon);
- }
}
}
}
sqlite3_stmt *pDepmask; /* Foreach depmask */
IdxScan *pIter;
- rc = idxPrepareStmt(pCtx->dbm, &pDepmask, pCtx->pzErrmsg,
+ rc = idxPrepareStmt(dbm, &pDepmask, pCtx->pzErrmsg,
"SELECT mask FROM depmask"
);
IdxScan *pNext;
for(pIter=pScan; pIter; pIter=pNext){
pNext = pIter->pNextScan;
-
}
}
if( rc==SQLITE_OK ) rc = rc2;
if( rc==SQLITE_OK ){
sqlite3_stmt *pLoop = 0;
- rc = idxPrepareStmt(dbm, &pLoop, pzErr, "SELECT name FROM aux.indexes");
+ rc = idxPrepareStmt(dbm, &pLoop, pzErr,"SELECT name||';' FROM aux.indexes");
if( rc==SQLITE_OK ){
while( SQLITE_ROW==sqlite3_step(pLoop) ){
bFound = 1;
- xOut(pOutCtx, sqlite3_column_text(pLoop, 0));
+ xOut(pOutCtx, (const char*)sqlite3_column_text(pLoop, 0));
}
rc = sqlite3_finalize(pLoop);
}
} {
SELECT * FROM t1 WHERE b>?;
} {
- CREATE INDEX t1_idx_00000062 ON t1(b)
+ CREATE INDEX t1_idx_00000062 ON t1(b);
0|0|0|SEARCH TABLE t1 USING INDEX t1_idx_00000062 (b>?)
}
} {
SELECT * FROM t1 WHERE b COLLATE nocase BETWEEN ? AND ?
} {
- CREATE INDEX t1_idx_3e094c27 ON t1(b COLLATE NOCASE)
+ CREATE INDEX t1_idx_3e094c27 ON t1(b COLLATE NOCASE);
0|0|0|SEARCH TABLE t1 USING INDEX t1_idx_3e094c27 (b>? AND b<?)
}
} {
SELECT a FROM t1 ORDER BY b;
} {
- CREATE INDEX t1_idx_00000062 ON t1(b)
+ CREATE INDEX t1_idx_00000062 ON t1(b);
0|0|0|SCAN TABLE t1 USING INDEX t1_idx_00000062
}
} {
SELECT a FROM t1 WHERE a=? ORDER BY b;
} {
- CREATE INDEX t1_idx_000123a7 ON t1(a, b)
+ CREATE INDEX t1_idx_000123a7 ON t1(a, b);
0|0|0|SEARCH TABLE t1 USING COVERING INDEX t1_idx_000123a7 (a=?)
}
} {
SELECT min(a) FROM t1
} {
- CREATE INDEX t1_idx_00000061 ON t1(a)
+ CREATE INDEX t1_idx_00000061 ON t1(a);
0|0|0|SEARCH TABLE t1 USING COVERING INDEX t1_idx_00000061
}
} {
SELECT * FROM t1 ORDER BY a, b, c;
} {
- CREATE INDEX t1_idx_033e95fe ON t1(a, b, c)
+ CREATE INDEX t1_idx_033e95fe ON t1(a, b, c);
0|0|0|SCAN TABLE t1 USING COVERING INDEX t1_idx_033e95fe
}
} {
SELECT * FROM t1 ORDER BY a ASC, b COLLATE nocase DESC, c ASC;
} {
- CREATE INDEX t1_idx_5be6e222 ON t1(a, b COLLATE NOCASE DESC, c)
+ CREATE INDEX t1_idx_5be6e222 ON t1(a, b COLLATE NOCASE DESC, c);
0|0|0|SCAN TABLE t1 USING COVERING INDEX t1_idx_5be6e222
}
} {
SELECT * FROM t1 WHERE a=?
} {
- CREATE INDEX t1_idx_00000061 ON t1(a)
+ CREATE INDEX t1_idx_00000061 ON t1(a);
0|0|0|SEARCH TABLE t1 USING INDEX t1_idx_00000061 (a=?)
}
} {
SELECT * FROM "t t" WHERE a=?
} {
- CREATE INDEX 't t_idx_00000061' ON 't t'(a)
+ CREATE INDEX 't t_idx_00000061' ON 't t'(a);
0|0|0|SEARCH TABLE t t USING INDEX t t_idx_00000061 (a=?)
}
} {
SELECT * FROM "t t" WHERE b BETWEEN ? AND ?
} {
- CREATE INDEX 't t_idx_00000062' ON 't t'(b)
+ CREATE INDEX 't t_idx_00000062' ON 't t'(b);
0|0|0|SEARCH TABLE t t USING INDEX t t_idx_00000062 (b>? AND b<?)
}
} {
SELECT * FROM t3 WHERE "b b" = ?
} {
- CREATE INDEX t3_idx_00050c52 ON t3('b b')
+ CREATE INDEX t3_idx_00050c52 ON t3('b b');
0|0|0|SEARCH TABLE t3 USING INDEX t3_idx_00050c52 (b b=?)
}
} {
SELECT * FROM t3 ORDER BY "b b"
} {
- CREATE INDEX t3_idx_00050c52 ON t3('b b')
+ CREATE INDEX t3_idx_00050c52 ON t3('b b');
0|0|0|SCAN TABLE t3 USING INDEX t3_idx_00050c52
}
} {
SELECT * FROM t5, t6 WHERE a=? AND b=c AND c=?
} {
- CREATE INDEX t5_idx_000123a7 ON t5(a, b)
- CREATE INDEX t6_idx_00000063 ON t6(c)
+ CREATE INDEX t5_idx_000123a7 ON t5(a, b);
+ CREATE INDEX t6_idx_00000063 ON t6(c);
0|0|1|SEARCH TABLE t6 USING INDEX t6_idx_00000063 (c=?)
0|1|0|SEARCH TABLE t5 USING COVERING INDEX t5_idx_000123a7 (a=? AND b=?)
}
} {
SELECT * FROM t7 WHERE a=? OR b=?
} {
- CREATE INDEX t7_idx_00000061 ON t7(a)
- CREATE INDEX t7_idx_00000062 ON t7(b)
+ CREATE INDEX t7_idx_00000061 ON t7(a);
+ CREATE INDEX t7_idx_00000062 ON t7(b);
0|0|0|SEARCH TABLE t7 USING INDEX t7_idx_00000061 (a=?)
0|0|0|SEARCH TABLE t7 USING INDEX t7_idx_00000062 (b=?)
}