1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-09-11 08:30:57 +03:00

First cut at a REINDEX command. Basic testing only. No documentation. (CVS 2072)

FossilOrigin-Name: 11dba47e61279bdf3be6f64a6259b877f3bf6155
This commit is contained in:
drh
2004-11-05 23:46:15 +00:00
parent b17131a084
commit 4343fea20f
7 changed files with 203 additions and 21 deletions

View File

@@ -1,5 +1,5 @@
C Use\ssqlite3NestedParse\sto\simplement\sDROP\sINDEX.\s(CVS\s2071)
D 2004-11-05T22:18:49
C First\scut\sat\sa\sREINDEX\scommand.\s\sBasic\stesting\sonly.\s\sNo\sdocumentation.\s(CVS\s2072)
D 2004-11-05T23:46:15
F Makefile.in c4d2416860f472a1e3393714d0372074197565df
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
@@ -31,7 +31,7 @@ F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
F src/btree.c bf0d3d59ec076f0a37378f8ac6090d157d925c24
F src/btree.h 861e40b759a195ba63819740e484390012cf81ab
F src/build.c e498f958ebb4678e103224edd3a5c2ebcc42d18f
F src/build.c 154e7a666a7b36da04c739a6af87d5e9bdcd0cda
F src/date.c 34bdb0082db7ec2a83ef00063f7b44e61ee19dad
F src/delete.c f0af21a1ede15524a5edd59fe10ef486283a1ee9
F src/expr.c be18081d2959a2cc53846d0fbedfec40fbfa1d6e
@@ -54,17 +54,17 @@ F src/os_win.c 9482dfc92f289b68205bb2c9315757c7e3946bfb
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c 868c67e4ff8a1785c06caaf483fddb5a95013af0
F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862
F src/parse.y 97247c0a89ca1667729db5035f1ee60140960984
F src/parse.y 8456726833755ecd6dac9bcd8af205c8dc419d01
F src/pragma.c 6a0ae7721e614c5a921e918ab5206d5e654f1a6f
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
F src/select.c 156990c636102bb6b8de85e7ff3396a62568476b
F src/shell.c 55adda3cf3c1cc2f6c1919aac17b2318f9c2a96f
F src/sqlite.h.in 4f97b5907acfd2a5068cb0cec9d5178816734db7
F src/sqliteInt.h 5d26b41b2ab7eeab1bd9db330ed7b7929d2ae875
F src/sqliteInt.h 9f846c4b752b9a1237e8250f8f8b3ecd1347a086
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
F src/tclsqlite.c 0302e3f42f015d132d1291f3388c06e86c24a008
F src/test1.c df1d1ca2c40cafefb9a29860f072c4d0fee1a7b5
F src/test1.c 91345097d94b4ad71f88776c2764e18c7955502a
F src/test2.c b11fa244fff02190707dd0879987c37c75e61fc8
F src/test3.c de9edf178c02707cd37fd80b54e4c2ea77251cc0
F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
@@ -160,6 +160,7 @@ F test/printf.test 92ba4c510b4fc61120ffa4a01820446ed917ae57
F test/progress.test 5ddba78cb6011fba36093973cfb3ac473b8fb96a x
F test/quick.test 2dca186ebd5c418a7699944ba3b5e437d765eddd
F test/quote.test 6d75cf635d93ba2484dc9cb378d88cbae9dc2c62
F test/reindex.test 1d579cdb942c5f9c26c7f8c94cdc3024cabf2644
F test/rollback.test 4097328d44510277244ef4fa51b22b2f11d7ef4c
F test/rowid.test 1ce3f1520d2082b0363e7d9bdef904cb72b9efe8
F test/select1.test 0e459a8066259445d707cc4f64ea00459441e29f
@@ -252,7 +253,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl fdacb0ba2d39831e8a6240d05a490026ad4c4e4c
P 47d8ebdaaddcb7a05e1917dd1dee2029c34228a4
R d45e3580de79d7367f59fbd57af5e6a1
P 0f81aa5b057eab908b46b70ea9e9a42bc2ee8c21
R 877c89049e39a4d803a0375d417e1d42
U drh
Z 4c43f2f11733856473822a7670e21c59
Z 82c5d66bdd823220be3997a2e30a2b5d

View File

@@ -1 +1 @@
0f81aa5b057eab908b46b70ea9e9a42bc2ee8c21
11dba47e61279bdf3be6f64a6259b877f3bf6155

View File

@@ -21,13 +21,8 @@
** BEGIN TRANSACTION
** COMMIT
** ROLLBACK
** PRAGMA
**
<<<<<<< build.c
** $Id: build.c,v 1.270 2004/11/05 22:18:49 drh Exp $
=======
** $Id: build.c,v 1.270 2004/11/05 22:18:49 drh Exp $
>>>>>>> 1.262
** $Id: build.c,v 1.271 2004/11/05 23:46:15 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -1989,6 +1984,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
int addr1; /* Address of top of loop */
int tnum; /* Root page of index */
Vdbe *v; /* Generate code into this virtual machine */
int isUnique; /* True for a unique index */
v = sqlite3GetVdbe(pParse);
if( v==0 ) return;
@@ -2007,8 +2003,11 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
sqlite3VdbeAddOp(v, OP_SetNumColumns, iTab, pTab->nCol);
addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
sqlite3GenerateIndexKey(v, pIndex, iTab);
sqlite3VdbeOp3(v, OP_IdxPut, iIdx, pIndex->onError!=OE_None,
"indexed columns are not unique", P3_STATIC);
isUnique = pIndex->onError!=OE_None;
sqlite3VdbeAddOp(v, OP_IdxPut, iIdx, isUnique);
if( isUnique ){
sqlite3VdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC);
}
sqlite3VdbeAddOp(v, OP_Next, iTab, addr1+1);
sqlite3VdbeChangeP2(v, addr1, sqlite3VdbeCurrentAddr(v));
sqlite3VdbeAddOp(v, OP_Close, iTab, 0);
@@ -2760,3 +2759,107 @@ sqlite3_value *sqlite3GetTransientValue(sqlite3 *db){
}
return db->pValue;
}
/*
** Check to see if pIndex uses the collating sequence pColl. Return
** true if it does and false if it does not.
*/
#ifndef SQLITE_OMIT_REINDEX
static int collationMatch(CollSeq *pColl, Index *pIndex){
int n = pIndex->keyInfo.nField;
CollSeq **pp = pIndex->keyInfo.aColl;
while( n-- ){
if( *pp==pColl ) return 1;
pp++;
}
return 0;
}
#endif
/*
** Recompute all indices of pTab that use the collating sequence pColl.
** If pColl==0 then recompute all indices of pTab.
*/
#ifndef SQLITE_OMIT_REINDEX
void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){
Index *pIndex; /* An index associated with pTab */
for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
if( pColl==0 || collationMatch(pColl,pIndex) ){
sqlite3BeginWriteOperation(pParse, 0, pTab->iDb);
sqlite3RefillIndex(pParse, pIndex, -1);
}
}
}
#endif
/*
** Recompute all indices of all tables in all databases where the
** indices use the collating sequence pColl. If pColl==0 then recompute
** all indices everywhere.
*/
#ifndef SQLITE_OMIT_REINDEX
void reindexDatabases(Parse *pParse, CollSeq *pColl){
Db *pDb; /* A single database */
int iDb; /* The database index number */
sqlite3 *db = pParse->db; /* The database connection */
HashElem *k; /* For looping over tables in pDb */
Table *pTab; /* A table in the database */
for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
if( pDb==0 ) continue;
for(k=sqliteHashFirst(&pDb->tblHash); k; k=sqliteHashNext(k)){
pTab = (Table*)sqliteHashData(k);
reindexTable(pParse, pTab, pColl);
}
}
}
#endif
/*
** Generate code for a REINDEX command. If the argument is present it
** is the name of a collating sequence and all indices that use that
** collating sequence should be reindexed. If no argument is present,
** then rebuild all indices
*/
#ifndef SQLITE_OMIT_REINDEX
void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */
char *z; /* Name of a table or index */
const char *zDb; /* Name of the database */
Table *pTab; /* A table in the database */
Index *pIndex; /* An index associated with pTab */
int iDb; /* The database index number */
sqlite3 *db = pParse->db; /* The database connection */
Token *pObjName; /* Name of the table or index to be reindexed */
if( pName1==0 ){
reindexDatabases(pParse, 0);
return;
}else if( pName2==0 ){
pColl = sqlite3FindCollSeq(db, db->enc, pName1->z, pName1->n, 0);
if( pColl ){
reindexDatabases(pParse, pColl);
return;
}
}
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName);
if( iDb<0 ) return;
z = sqlite3NameFromToken(pObjName);
zDb = db->aDb[iDb].zName;
pTab = sqlite3FindTable(db, z, zDb);
if( pTab ){
reindexTable(pParse, pTab, 0);
sqliteFree(z);
return;
}
pIndex = sqlite3FindIndex(db, z, zDb);
sqliteFree(z);
if( pIndex ){
sqlite3BeginWriteOperation(pParse, 0, iDb);
sqlite3RefillIndex(pParse, pIndex, -1);
return;
}
sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed");
}
#endif

View File

@@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.149 2004/11/05 05:10:29 drh Exp $
** @(#) $Id: parse.y,v 1.150 2004/11/05 23:46:15 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
@@ -920,3 +920,9 @@ database_kw_opt ::= .
cmd ::= DETACH database_kw_opt nm(D). {
sqlite3Detach(pParse, &D);
}
////////////////////////// REINDEX collation //////////////////////////////////
%ifndef SQLITE_OMIT_REINDEX
cmd ::= REINDEX. {sqlite3Reindex(pParse, 0, 0);}
cmd ::= REINDEX nm(X) dbnm(Y). {sqlite3Reindex(pParse, &X, &Y);}
%endif

View File

@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.334 2004/11/05 17:17:50 drh Exp $
** @(#) $Id: sqliteInt.h,v 1.335 2004/11/05 23:46:15 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -1455,5 +1455,6 @@ sqlite3_value *sqlite3ValueNew();
sqlite3_value *sqlite3GetTransientValue(sqlite3*db);
extern const unsigned char sqlite3UpperToLower[];
void sqlite3RootPageMoved(Db*, int, int);
void sqlite3Reindex(Parse*, Token*, Token*);
#endif

View File

@@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.107 2004/11/03 16:27:01 drh Exp $
** $Id: test1.c,v 1.108 2004/11/05 23:46:15 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -2558,6 +2558,11 @@ static void set_options(Tcl_Interp *interp){
#else
Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_OMIT_REINDEX
Tcl_SetVar2(interp, "sqlite_options", "reindex", "0", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "reindex", "1", TCL_GLOBAL_ONLY);
#endif
}
/*

66
test/reindex.test Normal file
View File

@@ -0,0 +1,66 @@
# 2004 November 5
#
# 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 REINDEX command.
#
# $Id: reindex.test,v 1.1 2004/11/05 23:46:15 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# There is nothing to test if REINDEX is disable for this build.
#
ifcapable {!reindex} {
finish_test
return
}
# Basic sanity checks.
#
do_test reindex-1.1 {
execsql {
CREATE TABLE t1(a,b);
INSERT INTO t1 VALUES(1,2);
INSERT INTO t1 VALUES(3,4);
CREATE INDEX i1 ON t1(a);
REINDEX;
}
} {}
integrity_check reindex-1.2
do_test reindex-1.3 {
execsql {
REINDEX t1;
}
} {}
integrity_check reindex-1.4
do_test reindex-1.5 {
execsql {
REINDEX i1;
}
} {}
integrity_check reindex-1.6
do_test reindex-1.7 {
execsql {
REINDEX main.t1;
}
} {}
do_test reindex-1.8 {
execsql {
REINDEX main.i1;
}
} {}
do_test reindex-1.9 {
catchsql {
REINDEX bogus
}
} {1 {unable to identify the object to be reindexed}}
finish_test