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:
19
manifest
19
manifest
@@ -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
|
||||
|
@@ -1 +1 @@
|
||||
0f81aa5b057eab908b46b70ea9e9a42bc2ee8c21
|
||||
11dba47e61279bdf3be6f64a6259b877f3bf6155
|
119
src/build.c
119
src/build.c
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
66
test/reindex.test
Normal 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
|
Reference in New Issue
Block a user