$(TOP)/src/utf.c \
$(TOP)/src/util.c \
$(TOP)/src/vdbe.c \
- $(TOP)/src/md5.c
+ $(TOP)/src/md5.c \
+ $(TOP)/src/where.c
# Header files used by all library source files.
#
-C First\scode\sfor\sthe\sANALYZE\scommand.\s\sMostly\suntested.\s\sThe\sanalysis\sis\nnot\sloaded\sinto\sthe\ssymbol\stables\sand\sis\snot\sused\sby\sthe\soptimizer.\s(CVS\s2560)
-D 2005-07-23T00:41:49
+C Full-coverage\stesting\sand\sdocumentation\sfor\sthe\sANALYZE\scommand.\s\sThe\nresults\sof\sanalysis\sare\sstill\snot\sloaded\sor\sused,\showever.\s(CVS\s2561)
+D 2005-07-23T02:17:03
F Makefile.in 22ea9c0fe748f591712d8fe3c6d972c6c173a165
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
-F main.mk b2d38013a10e1c6a821e3d117294bf785deecf97
+F main.mk c6712c0b26305f2da026d722caf3d9f8b6e187ea
F mkdll.sh 5ec23622515d5bf8969404e80cfb5e220ddf0512
F mkopcodec.awk bd46ad001c98dfbab07b1713cb8e692fa0e5415d
F mkopcodeh.awk 7563ad235670e864ead95cf672be3fe081450ae0
F sqlite3.def c413e514217736884254739a105c8c942fdf0c2f
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
F src/alter.c 03041f2464e22532601254f87cb49997fa21dcdf
-F src/analyze.c 0eb48929dd1caa21438b067c507b0ee55ce17047
+F src/analyze.c b849c23866b7da98373f7b380f40b2a5f371e962
F src/attach.c 3615dbe960cbee4aa5ea300b8a213dad36527b0f
F src/auth.c 18c5a0befe20f3a58a41e3ddd78f372faeeefe1f
F src/btree.c ec55bd70052cdd0958f3a0e79ad58d93561acb20
F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4
F src/select.c c611471052773b94af771693686bd5bcdbbb0dba
F src/shell.c 25b3217d7c64e6497225439d261a253a23efff26
-F src/sqlite.h.in 838382ed6b48d392366a55e07f49d9d71263e1fe
+F src/sqlite.h.in 7ccf2f61de2a0dca515e73708e561362e6c3d1e3
F src/sqliteInt.h 2925510c0233bb24c550fc5912fcdf0dd3a4421d
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
-F src/tclsqlite.c cccaf6b78c290d824cf8ea089b8b27377e545830
+F src/tclsqlite.c ef3276d0967cc0042bedcc1a7f09e0eb95cd3a8c
F src/test1.c 722c1444b5774705eb6eb11163343fc94ffe17f7
F src/test2.c 716c1809dba8e5be6093703e9cada99d627542dc
F src/test3.c 683e1e3819152ffd35da2f201e507228921148d0
F test/alter.test 9d6837a3d946b73df692b7cef2a7644d2e2f6bc6
F test/alter2.test 60ba0a7057dc71ad630a1cc7c487104346849d50
F test/alter3.test d4eecd8dbd008d0e66f1c201fa6dc2edca853c38
+F test/analyze.test a34554a015e9fdc478ae1660188feb0de4e43c2e
F test/attach.test f320e98bcca68d100cab7666a0c9a93ac5f236bd
F test/attach2.test 3396c012a39ddf7ba6b528d80bd79554168aa115
F test/attach3.test 63013383adc4380af69779f34f4af19bd49f7cbe
-F test/auth.test 5129bfe268133092ad2928b8644ef97fa4602b2e
+F test/auth.test 6a51c57219e246bdfd4454b3f7bd4136b44ad95c
F test/autoinc.test 2aba7dc87438d221e2f2ea0e3e7d5fb6812edf6d
F test/autovacuum.test cf2719b17659f7a011202ad05905654cedf26023
F test/autovacuum_crash.test 05a63b8805b20cfba7ace82856ce4ccdda075a31
F www/fileformat.tcl 900c95b9633abc3dcfc384d9ddd8eb4876793059
F www/formatchng.tcl 053ddb73646701353a5b1c9ca6274d5900739b45
F www/index.tcl 9527f4eed69739cf5f81b3d75e0478d1c84d0a8a
-F www/lang.tcl e0b9c55bf17a502b8f6f7731e5420278965b81a2
+F www/lang.tcl d55f580cff3f384ae82d29b1201babddf991f510
F www/lockingv3.tcl f59b19d6c8920a931f096699d6faaf61c05db55f
F www/mingw.tcl d96b451568c5d28545fefe0c80bee3431c73f69c
F www/nulls.tcl ec35193f92485b87b90a994a01d0171b58823fcf
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b
-P 1a573619f558d1d67775d17aabb9d704f82ad1a8
-R a3fdedefcb771a47f367010f865883f0
+P a4886b114d2ccb3841d3d219f6b97f67745b13c2
+R 65a6648aca434084253023a9ade3ab6b
U drh
-Z d92cfb5ebecb44f8fc7d777743031b10
+Z 5c397aa099a763af87ffe475ca34fcef
-a4886b114d2ccb3841d3d219f6b97f67745b13c2
\ No newline at end of file
+bd7583a5d63412785a9c5de54d25b509da241605
\ No newline at end of file
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
-** @(#) $Id: analyze.c,v 1.2 2005/07/23 00:41:49 drh Exp $
+** @(#) $Id: analyze.c,v 1.3 2005/07/23 02:17:03 drh Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"
/* Open the sqlite_stat1 table for writing.
*/
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
- sqlite3VdbeAddOp(v, OP_OpenWrite, iStatCur, 0);
+ sqlite3VdbeAddOp(v, OP_OpenWrite, iStatCur, iRootPage);
sqlite3VdbeAddOp(v, OP_SetNumColumns, iStatCur, 3);
}
/* Do no analysis for tables with fewer than 2 indices */
return;
}
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
+ pParse->db->aDb[pTab->iDb].zName ) ){
+ return;
+ }
+#endif
+
iIdxCur = pParse->nTab;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
/* Open a cursor to the index to be analyzed
/* Do the analysis.
*/
- sqlite3VdbeAddOp(v, OP_Rewind, iIdxCur, 0);
- topOfLoop = sqlite3VdbeCurrentAddr(v);
endOfLoop = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp(v, OP_Rewind, iIdxCur, endOfLoop);
+ topOfLoop = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp(v, OP_MemIncr, iMem, 0);
for(i=0; i<nCol; i++){
sqlite3VdbeAddOp(v, OP_Column, iIdxCur, i);
if( i==1 ) continue; /* Do not analyze the TEMP database */
analyzeDatabase(pParse, i);
}
- }else if( pName2==0 ){
+ }else if( pName2==0 || pName2->n==0 ){
/* Form 2: Analyze the database or table named */
iDb = sqlite3FindDb(db, pName1);
if( iDb>=0 ){
analyzeDatabase(pParse, iDb);
- return;
- }
- z = sqlite3NameFromToken(pName1);
- pTab = sqlite3LocateTable(pParse, z, 0);
- sqliteFree(z);
- if( pTab ){
- analyzeTable(pParse, pTab);
+ }else{
+ z = sqlite3NameFromToken(pName1);
+ pTab = sqlite3LocateTable(pParse, z, 0);
+ sqliteFree(z);
+ if( pTab ){
+ analyzeTable(pParse, pTab);
+ }
}
- return;
}else{
/* Form 3: Analyze the fully qualified table name */
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
** This header file defines the interface that the SQLite library
** presents to client programs.
**
-** @(#) $Id: sqlite.h.in,v 1.137 2005/07/09 02:39:40 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.138 2005/07/23 02:17:03 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#define SQLITE_DETACH 25 /* Database Name NULL */
#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */
#define SQLITE_REINDEX 27 /* Index Name NULL */
+#define SQLITE_ANALYZE 28 /* Table Name NULL */
/*
*************************************************************************
** A TCL Interface to SQLite
**
-** $Id: tclsqlite.c,v 1.127 2005/06/26 17:55:34 drh Exp $
+** $Id: tclsqlite.c,v 1.128 2005/07/23 02:17:03 drh Exp $
*/
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
case SQLITE_DETACH : zCode="SQLITE_DETACH"; break;
case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break;
case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break;
+ case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break;
default : zCode="????"; break;
}
Tcl_DStringInit(&str);
--- /dev/null
+# 2005 July 22
+#
+# 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.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.
+# This file implements tests for the ANALYZE command.
+#
+# $Id: analyze.test,v 1.1 2005/07/23 02:17:03 drh Exp $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# There is nothing to test if ANALYZE is disable for this build.
+#
+ifcapable {!analyze} {
+ finish_test
+ return
+}
+
+# Basic sanity checks.
+#
+do_test analyze-1.1 {
+ catchsql {
+ ANALYZE no_such_table
+ }
+} {1 {no such table: no_such_table}}
+do_test analyze-1.2 {
+ execsql {
+ SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1'
+ }
+} {0}
+do_test analyze-1.3 {
+ catchsql {
+ ANALYZE no_such_db.no_such_table
+ }
+} {1 {unknown database no_such_db}}
+do_test analyze-1.4 {
+ execsql {
+ SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1'
+ }
+} {0}
+do_test analyze-1.5 {
+ catchsql {
+ ANALYZE
+ }
+} {0 {}}
+do_test analyze-1.6 {
+ execsql {
+ SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1'
+ }
+} {1}
+do_test analyze-1.7 {
+ execsql {
+ SELECT * FROM sqlite_stat1
+ }
+} {}
+do_test analyze-1.8 {
+ catchsql {
+ ANALYZE main
+ }
+} {0 {}}
+do_test analyze-1.9 {
+ execsql {
+ SELECT * FROM sqlite_stat1
+ }
+} {}
+do_test analyze-1.10 {
+ catchsql {
+ CREATE TABLE t1(a,b);
+ ANALYZE main.t1;
+ }
+} {0 {}}
+do_test analyze-1.11 {
+ execsql {
+ SELECT * FROM sqlite_stat1
+ }
+} {}
+do_test analyze-1.12 {
+ catchsql {
+ ANALYZE t1;
+ }
+} {0 {}}
+do_test analyze-1.13 {
+ execsql {
+ SELECT * FROM sqlite_stat1
+ }
+} {}
+
+# Create some indices that can be analyzed. But do not yet add
+# data. Without data in the tables, no analysis is done.
+#
+do_test analyze-2.1 {
+ execsql {
+ CREATE INDEX t1i1 ON t1(a);
+ ANALYZE main.t1;
+ SELECT * FROM sqlite_stat1 ORDER BY idx;
+ }
+} {}
+do_test analyze-2.2 {
+ execsql {
+ CREATE INDEX t1i2 ON t1(b);
+ ANALYZE t1;
+ SELECT * FROM sqlite_stat1 ORDER BY idx;
+ }
+} {}
+do_test analyze-2.3 {
+ execsql {
+ CREATE INDEX t1i3 ON t1(a,b);
+ ANALYZE main;
+ SELECT * FROM sqlite_stat1 ORDER BY idx;
+ }
+} {}
+
+# Start adding data to the table. Verify that the analysis
+# is done correctly.
+#
+do_test analyze-3.1 {
+ execsql {
+ INSERT INTO t1 VALUES(1,2);
+ INSERT INTO t1 VALUES(1,3);
+ ANALYZE main.t1;
+ SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
+ }
+} {t1i1 2 t1i2 1 t1i3 {2 1}}
+do_test analyze-3.2 {
+ execsql {
+ INSERT INTO t1 VALUES(1,4);
+ INSERT INTO t1 VALUES(1,5);
+ ANALYZE t1;
+ SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
+ }
+} {t1i1 4 t1i2 1 t1i3 {4 1}}
+do_test analyze-3.3 {
+ execsql {
+ INSERT INTO t1 VALUES(2,5);
+ ANALYZE main;
+ SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
+ }
+} {t1i1 3 t1i2 2 t1i3 {3 1}}
+do_test analyze-3.4 {
+ execsql {
+ CREATE TABLE t2 AS SELECT * FROM t1;
+ CREATE INDEX t2i1 ON t2(a);
+ CREATE INDEX t2i2 ON t2(b);
+ CREATE INDEX t2i3 ON t2(a,b);
+ ANALYZE;
+ SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
+ }
+} {t1i1 3 t1i2 2 t1i3 {3 1} t2i1 3 t2i2 2 t2i3 {3 1}}
+do_test analyze-3.5 {
+ execsql {
+ DROP INDEX t2i3;
+ ANALYZE t1;
+ SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
+ }
+} {t1i1 3 t1i2 2 t1i3 {3 1} t2i1 3 t2i2 2 t2i3 {3 1}}
+do_test analyze-3.6 {
+ execsql {
+ ANALYZE t2;
+ SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
+ }
+} {t1i1 3 t1i2 2 t1i3 {3 1} t2i1 3 t2i2 2}
+do_test analyze-3.7 {
+ execsql {
+ DROP INDEX t2i2;
+ ANALYZE t2;
+ SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
+ }
+} {t1i1 3 t1i2 2 t1i3 {3 1}}
+do_test analyze-3.8 {
+ execsql {
+ CREATE TABLE t3 AS SELECT a, b, rowid AS c, 'hi' AS d FROM t1;
+ CREATE INDEX t3i1 ON t3(a);
+ CREATE INDEX t3i2 ON t3(a,b,c,d);
+ CREATE INDEX t3i3 ON t3(d,b,c,a);
+ DROP TABLE t1;
+ DROP TABLE t2;
+ ANALYZE;
+ SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
+ }
+} {t3i1 3 t3i2 {3 1 1 1} t3i3 {5 2 1 1}}
+
+
+finish_test
# focus of this script is testing the ATTACH and DETACH commands
# and related functionality.
#
-# $Id: auth.test,v 1.27 2005/03/29 03:11:00 danielk1977 Exp $
+# $Id: auth.test,v 1.28 2005/07/23 02:17:03 drh Exp $
#
set testdir [file dirname $argv0]
} ;# ifcapable reindex
+ifcapable analyze {
+ proc auth {code args} {
+ if {$code=="SQLITE_ANALYZE"} {
+ set ::authargs [concat $::authargs $args]
+ }
+ return SQLITE_OK
+ }
+ do_test auth-1.294 {
+ set ::authargs {}
+ execsql {
+ CREATE TABLE t4(a,b,c);
+ CREATE INDEX t4i1 ON t4(a);
+ CREATE INDEX t4i2 ON t4(b,a,c);
+ INSERT INTO t4 VALUES(1,2,3);
+ ANALYZE;
+ }
+ set ::authargs
+ } {t4 {} main {}}
+ do_test auth-1.295 {
+ execsql {
+ SELECT count(*) FROM sqlite_stat1;
+ }
+ } 2
+ proc auth {code args} {
+ if {$code=="SQLITE_ANALYZE"} {
+ set ::authargs [concat $::authargs $args]
+ return SQLITE_DENY
+ }
+ return SQLITE_OK
+ }
+ do_test auth-1.296 {
+ set ::authargs {}
+ catchsql {
+ ANALYZE;
+ }
+ } {1 {not authorized}}
+ do_test auth-1.297 {
+ execsql {
+ SELECT count(*) FROM sqlite_stat1;
+ }
+ } 2
+} ;# ifcapable analyze
+
do_test auth-2.1 {
proc auth {code arg1 arg2 arg3 arg4} {
if {$code=="SQLITE_READ" && $arg1=="t3" && $arg2=="x"} {
#
# Run this Tcl script to generate the lang-*.html files.
#
-set rcsid {$Id: lang.tcl,v 1.94 2005/07/22 23:56:50 drh Exp $}
+set rcsid {$Id: lang.tcl,v 1.95 2005/07/23 02:17:03 drh Exp $}
source common.tcl
if {[llength $argv]>0} {
{{DETACH DATABASE} detach}
{REINDEX reindex}
{{ALTER TABLE} altertable}
+ {{ANALYZE} analyze}
}] {
foreach {s_title s_tag} $section {}
puts "<li><a href=\"[slink $s_tag]\">$s_title</a></li>"
is <a href="lang_vacuum.html">VACUUM</a>ed.</p>
}
+Section {ANALYZE} analyze
+
+Syntax {sql-statement} {
+ ANALYZE
+}
+Syntax {sql-statement} {
+ ANALYZE <database-name>
+}
+Syntax {sql-statement} {
+ ANALYZE [<database-name> .] <table-name>
+}
+
+puts {
+<p>The ANALYZE command gathers statistics about indices and stores them
+in a special tables in the database where the query optimizer can use
+them to help make better index choices.
+If no arguments are given, all indices in all attached databases are
+analyzed. If a database name is given as the argument, all indices
+in that one database are analyzed. If the argument is a table name,
+then only indices associated with that one table are analyzed.</p>
+
+<p>The initial implementation stores all statistics in a single
+table named <b>sqlite_stat1</b>. Future enhancements may create
+additional tables with the same name pattern except with the "1"
+changed to a different digit. The <b>sqlite_stat1</b> table cannot
+be DROPped, but it all the content can be DELETEd which as the
+same effect.</p>
+}
+
Section {ATTACH DATABASE} attach
Syntax {sql-statement} {
puts {
<p>The REINDEX command is used to delete and recreate indices from scratch.
-This is primarily useful when the definition of a collation sequence has
-changed.
+This is useful when the definition of a collation sequence has changed.
</p>
<p>In the first form, all indices in all attached databases that use the