Here begins an experimental branch for exploring the idea of a partial index.

This check-in is able to parse a WHERE clause on a CREATE INDEX statement, but
does not actually do anythingn with that WHERE clause yet.

FossilOrigin-Name: 6794b2dcb48b3507caccfc7867fc185818cf8291
This commit is contained in:
drh 2013-07-31 18:12:26 +00:00
parent 6b36e82c7b
commit 1fe0537e51
6 changed files with 61 additions and 19 deletions

View File

@ -1,5 +1,5 @@
C Reduce\sthe\ssize\sof\sthe\sstack\srequired\sby\sthe\scodeOneLoopStart()\sfunction\sin\nwhere.c. C Here\sbegins\san\sexperimental\sbranch\sfor\sexploring\sthe\sidea\sof\sa\spartial\sindex.\nThis\scheck-in\sis\sable\sto\sparse\sa\sWHERE\sclause\son\sa\sCREATE\sINDEX\sstatement,\sbut\ndoes\snot\sactually\sdo\sanythingn\swith\sthat\sWHERE\sclause\syet.
D 2013-07-30T15:10:32.747 D 2013-07-31T18:12:26.006
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -166,7 +166,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a
F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca
F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2 F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
F src/build.c 42239cfd95533e4aacf4d58b4724c8f858de5ced F src/build.c c2903be4a825d6be0a518f87b60e0dcf878782d3
F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267 F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267
@ -206,7 +206,7 @@ F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847
F src/os_win.c 074cb2b9bca6a1c2bd72acf04666cdc554bfaa9b F src/os_win.c 074cb2b9bca6a1c2bd72acf04666cdc554bfaa9b
F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b
F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1 F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
F src/parse.y 9acfcc83ddbf0cf82f0ed9582ccf0ad6c366ff37 F src/parse.y a950b48d4363f44dd98fef8a89fbd48970ebd9ce
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938 F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938
@ -221,7 +221,7 @@ F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd
F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 89b52c053ebafa76f03bab4f0c8ee1e390eb7489 F src/sqliteInt.h c99f22c5bda01f07e2f9a9a8cb2c0b9adeea696c
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@ -589,6 +589,7 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7 F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7
F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026 F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026
F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33 F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33
F test/index6.test cbd74aa8604e29982438a7defae9fadaf9605336
F test/indexedby.test 0e959308707c808515c3a51363f7a9835027108c F test/indexedby.test 0e959308707c808515c3a51363f7a9835027108c
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
@ -1103,7 +1104,10 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
P 9e819f0f12b6f2a8e0e7a90251b3115ff1595f25 P eb6d4278b8516e0571269049d1eaa55066f51b1a
R 8a77f3488eeca7f033bc07ab4b9db562 R d0aa2f7065f4153ebb66a1af4210e515
T *branch * partial-indices
T *sym-partial-indices *
T -sym-trunk *
U drh U drh
Z 51b3ad13ced3eb326ea64314852a899d Z cfed8379e8335c37848dda6e7de0acdf

View File

@ -1 +1 @@
eb6d4278b8516e0571269049d1eaa55066f51b1a 6794b2dcb48b3507caccfc7867fc185818cf8291

View File

@ -382,6 +382,7 @@ static void freeIndex(sqlite3 *db, Index *p){
#ifndef SQLITE_OMIT_ANALYZE #ifndef SQLITE_OMIT_ANALYZE
sqlite3DeleteIndexSamples(db, p); sqlite3DeleteIndexSamples(db, p);
#endif #endif
sqlite3ExprDelete(db, p->pPartIdxWhere);
sqlite3DbFree(db, p->zColAff); sqlite3DbFree(db, p->zColAff);
sqlite3DbFree(db, p); sqlite3DbFree(db, p);
} }
@ -1225,7 +1226,8 @@ void sqlite3AddPrimaryKey(
#endif #endif
}else{ }else{
Index *p; Index *p;
p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0); p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0,
0, sortOrder, 0);
if( p ){ if( p ){
p->autoIndex = 2; p->autoIndex = 2;
} }
@ -2483,6 +2485,7 @@ Index *sqlite3CreateIndex(
int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
Token *pStart, /* The CREATE token that begins this statement */ Token *pStart, /* The CREATE token that begins this statement */
Token *pEnd, /* The ")" that closes the CREATE INDEX statement */ Token *pEnd, /* The ")" that closes the CREATE INDEX statement */
Expr *pPIWhere, /* WHERE clause for partial indices */
int sortOrder, /* Sort order of primary key when pList==NULL */ int sortOrder, /* Sort order of primary key when pList==NULL */
int ifNotExist /* Omit error if index already exists */ int ifNotExist /* Omit error if index already exists */
){ ){
@ -2699,6 +2702,8 @@ Index *sqlite3CreateIndex(
pIndex->uniqNotNull = onError==OE_Abort; pIndex->uniqNotNull = onError==OE_Abort;
pIndex->autoIndex = (u8)(pName==0); pIndex->autoIndex = (u8)(pName==0);
pIndex->pSchema = db->aDb[iDb].pSchema; pIndex->pSchema = db->aDb[iDb].pSchema;
pIndex->pPartIdxWhere = pPIWhere;
pPIWhere = 0;
assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
/* Check to see if we should honor DESC requests on index columns /* Check to see if we should honor DESC requests on index columns
@ -2933,10 +2938,8 @@ Index *sqlite3CreateIndex(
/* Clean up before exiting */ /* Clean up before exiting */
exit_create_index: exit_create_index:
if( pIndex ){ if( pIndex ) freeIndex(db, pIndex);
sqlite3DbFree(db, pIndex->zColAff); sqlite3ExprDelete(db, pPIWhere);
sqlite3DbFree(db, pIndex);
}
sqlite3ExprListDelete(db, pList); sqlite3ExprListDelete(db, pList);
sqlite3SrcListDelete(db, pTblName); sqlite3SrcListDelete(db, pTblName);
sqlite3DbFree(db, zName); sqlite3DbFree(db, zName);

View File

@ -300,7 +300,8 @@ ccons ::= NULL onconf.
ccons ::= NOT NULL onconf(R). {sqlite3AddNotNull(pParse, R);} ccons ::= NOT NULL onconf(R). {sqlite3AddNotNull(pParse, R);}
ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I). ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I).
{sqlite3AddPrimaryKey(pParse,0,R,I,Z);} {sqlite3AddPrimaryKey(pParse,0,R,I,Z);}
ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0);} ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,
0,0,0,0);}
ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X.pExpr);} ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X.pExpr);}
ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R). ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R).
{sqlite3CreateForeignKey(pParse,0,&T,TA,R);} {sqlite3CreateForeignKey(pParse,0,&T,TA,R);}
@ -349,7 +350,7 @@ tcons ::= CONSTRAINT nm(X). {pParse->constraintName = X;}
tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R). tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R).
{sqlite3AddPrimaryKey(pParse,X,R,I,0);} {sqlite3AddPrimaryKey(pParse,X,R,I,0);}
tcons ::= UNIQUE LP idxlist(X) RP onconf(R). tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
{sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0);} {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0,0);}
tcons ::= CHECK LP expr(E) RP onconf. tcons ::= CHECK LP expr(E) RP onconf.
{sqlite3AddCheckConstraint(pParse,E.pExpr);} {sqlite3AddCheckConstraint(pParse,E.pExpr);}
tcons ::= FOREIGN KEY LP idxlist(FA) RP tcons ::= FOREIGN KEY LP idxlist(FA) RP
@ -1125,10 +1126,10 @@ nexprlist(A) ::= expr(Y).
///////////////////////////// The CREATE INDEX command /////////////////////// ///////////////////////////// The CREATE INDEX command ///////////////////////
// //
cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D) cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D)
ON nm(Y) LP idxlist(Z) RP(E). { ON nm(Y) LP idxlist(Z) RP(E) where_opt(W). {
sqlite3CreateIndex(pParse, &X, &D, sqlite3CreateIndex(pParse, &X, &D,
sqlite3SrcListAppend(pParse->db,0,&Y,0), Z, U, sqlite3SrcListAppend(pParse->db,0,&Y,0), Z, U,
&S, &E, SQLITE_SO_ASC, NE); &S, &E, W, SQLITE_SO_ASC, NE);
} }
%type uniqueflag {int} %type uniqueflag {int}

View File

@ -1538,6 +1538,7 @@ struct Index {
Schema *pSchema; /* Schema containing this index */ Schema *pSchema; /* Schema containing this index */
u8 *aSortOrder; /* for each column: True==DESC, False==ASC */ u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
char **azColl; /* Array of collation sequence names for index */ char **azColl; /* Array of collation sequence names for index */
Expr *pPartIdxWhere; /* WHERE clause for partial indices */
int tnum; /* DB Page containing root of this index */ int tnum; /* DB Page containing root of this index */
u16 nColumn; /* Number of columns in table used by this index */ u16 nColumn; /* Number of columns in table used by this index */
u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
@ -2783,7 +2784,7 @@ void sqlite3SrcListAssignCursors(Parse*, SrcList*);
void sqlite3IdListDelete(sqlite3*, IdList*); void sqlite3IdListDelete(sqlite3*, IdList*);
void sqlite3SrcListDelete(sqlite3*, SrcList*); void sqlite3SrcListDelete(sqlite3*, SrcList*);
Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
Token*, int, int); Token*, Expr*, int, int);
void sqlite3DropIndex(Parse*, SrcList*, int); void sqlite3DropIndex(Parse*, SrcList*, int);
int sqlite3Select(Parse*, Select*, SelectDest*); int sqlite3Select(Parse*, Select*, SelectDest*);
Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,

33
test/index6.test Normal file
View File

@ -0,0 +1,33 @@
# 2013-07-31
#
# 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.
#
#***********************************************************************
#
# Test cases for partial indices
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
load_static_extension db wholenumber;
do_test index6-1.1 {
execsql {
CREATE TABLE t1(a,b);
CREATE INDEX t1a ON t1(a) WHERE a IS NOT NULL;
CREATE INDEX t1b ON t1(b) WHERE b>10;
CREATE VIRTUAL TABLE nums USING wholenumber;
INSERT INTO t1(a,b)
SELECT CASE WHEN value%3!=0 THEN value END, value
FROM nums WHERE value<=20;
SELECT count(a), count(b) FROM t1;
}
} {14 20}
finish_test