1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-20 07:41:32 +03:00

Allow INDEXED BY and NOT INDEXED to be used in UPDATE and DELETE statements. (CVS 5772)

FossilOrigin-Name: 83a7e446b2d4846a6f92bd831a2adaa265f5a786
This commit is contained in:
danielk1977
2008-10-06 16:18:39 +00:00
parent 6ef7f85801
commit b1c685b0c8
8 changed files with 131 additions and 56 deletions

View File

@@ -1,5 +1,5 @@
C Add\sa\stest\sscript\sto\sverify\sthat\sticket\s#3419\sstays\sfixed.\s(CVS\s5771) C Allow\sINDEXED\sBY\sand\sNOT\sINDEXED\sto\sbe\sused\sin\sUPDATE\sand\sDELETE\sstatements.\s(CVS\s5772)
D 2008-10-06T15:31:13 D 2008-10-06T16:18:40
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in e4ab842f9a64ef61d57093539a8aab76b12810db F Makefile.in e4ab842f9a64ef61d57093539a8aab76b12810db
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -102,11 +102,11 @@ F src/btmutex.c 709cad2cdca0afd013f0f612363810e53f59ec53
F src/btree.c 64a38df6f0a9997563418ed194984b81e4ab3694 F src/btree.c 64a38df6f0a9997563418ed194984b81e4ab3694
F src/btree.h 6371c5e599fab391a150c96afbc10062b276d107 F src/btree.h 6371c5e599fab391a150c96afbc10062b276d107
F src/btreeInt.h e38e9b2b285f40f5bc0a6664f630d4a141622f16 F src/btreeInt.h e38e9b2b285f40f5bc0a6664f630d4a141622f16
F src/build.c 5097bb7978bfdae4ae052abc16aa00c1054b7956 F src/build.c 8714bd809583bbe07bf22d0e1808a3fc31abe330
F src/callback.c 7a40fd44da3eb89e7f6eff30aa6f940c45d73a97 F src/callback.c 7a40fd44da3eb89e7f6eff30aa6f940c45d73a97
F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
F src/date.c 5c092296c03d658e84884121a694150964d6861d F src/date.c 5c092296c03d658e84884121a694150964d6861d
F src/delete.c 52c3614b1dc815f54d64a98dc65a393737f68b91 F src/delete.c 924c43df7533479d0aa93dc0eed32c9b8cf64c9f
F src/expr.c 30973b017bf95ca767f5eec64918c8afc425488d F src/expr.c 30973b017bf95ca767f5eec64918c8afc425488d
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
F src/func.c 8431b40a7843d1024145684d303c55b4ee087bbe F src/func.c 8431b40a7843d1024145684d303c55b4ee087bbe
@@ -139,7 +139,7 @@ F src/os_unix.c f33b69d8a85372b270fe37ee664a4c2140a5217d
F src/os_win.c 04033a86a39f49cb8e348f515eb0116aa9d36678 F src/os_win.c 04033a86a39f49cb8e348f515eb0116aa9d36678
F src/pager.c 44eba010e81dcc9b772401b90d6a1c61ec24345b F src/pager.c 44eba010e81dcc9b772401b90d6a1c61ec24345b
F src/pager.h 9c1917be28fff58118e1fe0ddbc7adfb8dd4f44d F src/pager.h 9c1917be28fff58118e1fe0ddbc7adfb8dd4f44d
F src/parse.y c69312dff9285f6638b209189d4166dd3a985c81 F src/parse.y d8edf095cd9f1a0083e6ff6b964396870523dc0d
F src/pcache.c f8d7beceba164a34441ac37e88abb3a404f968a7 F src/pcache.c f8d7beceba164a34441ac37e88abb3a404f968a7
F src/pcache.h 28d9ce2d66909db1f01652586450b62b64793093 F src/pcache.h 28d9ce2d66909db1f01652586450b62b64793093
F src/pragma.c 0b1c2d2a241dd79a7361bbeb8ff575a9e9d7cd71 F src/pragma.c 0b1c2d2a241dd79a7361bbeb8ff575a9e9d7cd71
@@ -147,11 +147,11 @@ F src/prepare.c c7e00ed1b0bdcf699b1aad651247d4dc3d281b0b
F src/printf.c 785f87120589c1db672e37c6eb1087c456e6f84d F src/printf.c 785f87120589c1db672e37c6eb1087c456e6f84d
F src/random.c 11bbdf7def3746a762fbdb56c9d04648135ad6d8 F src/random.c 11bbdf7def3746a762fbdb56c9d04648135ad6d8
F src/resolve.c 1971ff6996f1a73303339acf7f1de8497546045d F src/resolve.c 1971ff6996f1a73303339acf7f1de8497546045d
F src/select.c 75d4ffe971e25831125ea165c0c580df00f4c403 F src/select.c 34f32ee034289d72aa459fef40565bb74c76af24
F src/shell.c d83b578a8ccdd3e0e7fef4388a0887ce9f810967 F src/shell.c d83b578a8ccdd3e0e7fef4388a0887ce9f810967
F src/sqlite.h.in ea235b37a691b32e7941baa70fb0afaf6377dbb4 F src/sqlite.h.in ea235b37a691b32e7941baa70fb0afaf6377dbb4
F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e
F src/sqliteInt.h 1806947aac72ba3ea6de3b9de5c66e3d257e8fe7 F src/sqliteInt.h 6c08ddc70e1c9b0581778543af6985342c5516f0
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8 F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76 F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
F src/table.c 22744786199c9195720c15a7a42cb97b2e2728d8 F src/table.c 22744786199c9195720c15a7a42cb97b2e2728d8
@@ -372,7 +372,7 @@ F test/incrvacuum_ioerr.test 57d2f5777ab13fa03b87b262a4ea1bad5cfc0291
F test/index.test cbf301cdb2da43e4eac636c3400c2439af1834ad F test/index.test cbf301cdb2da43e4eac636c3400c2439af1834ad
F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
F test/index3.test 727d55dceb9a4ec36675057bb5becfc265e28ca6 F test/index3.test 727d55dceb9a4ec36675057bb5becfc265e28ca6
F test/indexedby.test 5e54a6b25ac619502a4960c1bf7ca93bb23da5df F test/indexedby.test 03af52375e50d146e78f56442b6677d2932c4963
F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908 F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908
F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435 F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435
F test/insert3.test 9a4ef3526fd3cca8b05278020ec3100448b4c677 F test/insert3.test 9a4ef3526fd3cca8b05278020ec3100448b4c677
@@ -640,7 +640,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1 F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P 24891902fa625445aa47ae930f0cb340cc73d25d P c3cf54a1b6bbaaeab4cab701c6cbbed02695facc
R 078d46958e9975c6cde4a1174680baa8 R ca83b644149fe533cdd795f52e48a148
U drh U danielk1977
Z 32ce6a1b9f1606eebd07bae951617e0e Z c3b964ea90e3130652cb73cc4202d059

View File

@@ -1 +1 @@
c3cf54a1b6bbaaeab4cab701c6cbbed02695facc 83a7e446b2d4846a6f92bd831a2adaa265f5a786

View File

@@ -22,7 +22,7 @@
** COMMIT ** COMMIT
** ROLLBACK ** ROLLBACK
** **
** $Id: build.c,v 1.497 2008/10/06 05:32:19 danielk1977 Exp $ ** $Id: build.c,v 1.498 2008/10/06 16:18:40 danielk1977 Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -3116,7 +3116,6 @@ SrcList *sqlite3SrcListAppendFromTerm(
Token *pTable, /* Name of the table to add to the FROM clause */ Token *pTable, /* Name of the table to add to the FROM clause */
Token *pDatabase, /* Name of the database containing pTable */ Token *pDatabase, /* Name of the database containing pTable */
Token *pAlias, /* The right-hand side of the AS subexpression */ Token *pAlias, /* The right-hand side of the AS subexpression */
Token *pIndexedBy, /* Token from INDEXED BY clause, if any */
Select *pSubquery, /* A subquery used in place of a table name */ Select *pSubquery, /* A subquery used in place of a table name */
Expr *pOn, /* The ON clause of a join */ Expr *pOn, /* The ON clause of a join */
IdList *pUsing /* The USING clause of a join */ IdList *pUsing /* The USING clause of a join */
@@ -3134,19 +3133,30 @@ SrcList *sqlite3SrcListAppendFromTerm(
if( pAlias && pAlias->n ){ if( pAlias && pAlias->n ){
pItem->zAlias = sqlite3NameFromToken(db, pAlias); pItem->zAlias = sqlite3NameFromToken(db, pAlias);
} }
if( pIndexedBy && pIndexedBy->n==1 && !pIndexedBy->z ){
/* A "NOT INDEXED" clause was supplied. See parse.y
** construct "indexed_opt" for details. */
pItem->notIndexed = 1;
}else{
pItem->zIndex = sqlite3NameFromToken(db, pIndexedBy);
}
pItem->pSelect = pSubquery; pItem->pSelect = pSubquery;
pItem->pOn = pOn; pItem->pOn = pOn;
pItem->pUsing = pUsing; pItem->pUsing = pUsing;
return p; return p;
} }
/*
** Add an INDEXED BY or NOT INDEXED clause to the most recently added
** element of the source-list passed as the second argument.
*/
void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
if( pIndexedBy && p && p->nSrc>0 ){
struct SrcList_item *pItem = &p->a[p->nSrc-1];
assert( pItem->notIndexed==0 && pItem->zIndex==0 );
if( pIndexedBy->n==1 && !pIndexedBy->z ){
/* A "NOT INDEXED" clause was supplied. See parse.y
** construct "indexed_opt" for details. */
pItem->notIndexed = 1;
}else{
pItem->zIndex = sqlite3NameFromToken(pParse->db, pIndexedBy);
}
}
}
/* /*
** When building up a FROM clause in the parser, the join operator ** When building up a FROM clause in the parser, the join operator
** is initially attached to the left operand. But the code generator ** is initially attached to the left operand. But the code generator

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser ** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements. ** in order to generate code for DELETE FROM statements.
** **
** $Id: delete.c,v 1.176 2008/10/06 05:32:19 danielk1977 Exp $ ** $Id: delete.c,v 1.177 2008/10/06 16:18:40 danielk1977 Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -22,16 +22,17 @@
** are found, return a pointer to the last table. ** are found, return a pointer to the last table.
*/ */
Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
Table *pTab = 0; struct SrcList_item *pItem = pSrc->a;
int i; Table *pTab;
struct SrcList_item *pItem; assert( pItem && pSrc->nSrc==1 );
for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase); pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
sqlite3DeleteTable(pItem->pTab); sqlite3DeleteTable(pItem->pTab);
pItem->pTab = pTab; pItem->pTab = pTab;
if( pTab ){ if( pTab ){
pTab->nRef++; pTab->nRef++;
} }
if( sqlite3IndexedByLookup(pParse, pItem) ){
pTab = 0;
} }
return pTab; return pTab;
} }
@@ -106,7 +107,7 @@ void sqlite3MaterializeView(
pWhere = sqlite3ExprDup(db, pWhere); pWhere = sqlite3ExprDup(db, pWhere);
viewName.z = (u8*)pView->zName; viewName.z = (u8*)pView->zName;
viewName.n = (unsigned int)strlen((const char*)viewName.z); viewName.n = (unsigned int)strlen((const char*)viewName.z);
pFrom = sqlite3SrcListAppendFromTerm(pParse, 0, 0, 0, &viewName,0,pDup,0,0); pFrom = sqlite3SrcListAppendFromTerm(pParse, 0, 0, 0, &viewName, pDup, 0,0);
pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0); pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
} }
sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);

View File

@@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing ** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens. ** numeric codes for all of the tokens.
** **
** @(#) $Id: parse.y,v 1.253 2008/10/06 05:32:19 danielk1977 Exp $ ** @(#) $Id: parse.y,v 1.254 2008/10/06 16:18:40 danielk1977 Exp $
*/ */
// All token codes are small integers with #defines that begin with "TK_" // All token codes are small integers with #defines that begin with "TK_"
@@ -457,12 +457,13 @@ stl_prefix(A) ::= seltablist(X) joinop(Y). {
} }
stl_prefix(A) ::= . {A = 0;} stl_prefix(A) ::= . {A = 0;}
seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) indexed_opt(I) on_opt(N) using_opt(U). { seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) indexed_opt(I) on_opt(N) using_opt(U). {
A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,&I,0,N,U); A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,0,N,U);
sqlite3SrcListIndexedBy(pParse, A, &I);
} }
%ifndef SQLITE_OMIT_SUBQUERY %ifndef SQLITE_OMIT_SUBQUERY
seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP
as(Z) on_opt(N) using_opt(U). { as(Z) on_opt(N) using_opt(U). {
A = sqlite3SrcListAppendFromTerm(pParse,X,0,0,&Z,0,S,N,U); A = sqlite3SrcListAppendFromTerm(pParse,X,0,0,&Z,S,N,U);
} }
// A seltablist_paren nonterminal represents anything in a FROM that // A seltablist_paren nonterminal represents anything in a FROM that
@@ -506,7 +507,7 @@ on_opt(N) ::= . {N = 0;}
// in the token. // in the token.
// //
// If there is a "NOT INDEXED" clause, then (z==0 && n==1), which is // If there is a "NOT INDEXED" clause, then (z==0 && n==1), which is
// normally illegal. The sqlite3SrcListAppendFromTerm() function // normally illegal. The sqlite3SrcListIndexedBy() function
// recognizes and interprets this as a special case. // recognizes and interprets this as a special case.
// //
%type indexed_opt {Token} %type indexed_opt {Token}
@@ -577,7 +578,10 @@ limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y).
/////////////////////////// The DELETE statement ///////////////////////////// /////////////////////////// The DELETE statement /////////////////////////////
// //
cmd ::= DELETE FROM fullname(X) where_opt(Y). {sqlite3DeleteFrom(pParse,X,Y);} cmd ::= DELETE FROM fullname(X) indexed_opt(I) where_opt(Y). {
sqlite3SrcListIndexedBy(pParse, X, &I);
sqlite3DeleteFrom(pParse,X,Y);
}
%type where_opt {Expr*} %type where_opt {Expr*}
%destructor where_opt {sqlite3ExprDelete(pParse->db, $$);} %destructor where_opt {sqlite3ExprDelete(pParse->db, $$);}
@@ -587,7 +591,8 @@ where_opt(A) ::= WHERE expr(X). {A = X;}
////////////////////////// The UPDATE command //////////////////////////////// ////////////////////////// The UPDATE command ////////////////////////////////
// //
cmd ::= UPDATE orconf(R) fullname(X) SET setlist(Y) where_opt(Z). { cmd ::= UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(Z). {
sqlite3SrcListIndexedBy(pParse, X, &I);
sqlite3ExprListCheckLength(pParse,Y,"set list"); sqlite3ExprListCheckLength(pParse,Y,"set list");
sqlite3Update(pParse,X,Y,Z,R); sqlite3Update(pParse,X,Y,Z,R);
} }

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser ** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite. ** to handle SELECT statements in SQLite.
** **
** $Id: select.c,v 1.477 2008/10/06 05:32:19 danielk1977 Exp $ ** $Id: select.c,v 1.478 2008/10/06 16:18:40 danielk1977 Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -2882,6 +2882,31 @@ static int minMaxQuery(Parse *pParse, Select *p){
return WHERE_ORDERBY_NORMAL; return WHERE_ORDERBY_NORMAL;
} }
/*
** If the source-list item passed as an argument was augmented with an
** INDEXED BY clause, then try to locate the specified index. If there
** was such a clause and the named index cannot be found, return
** SQLITE_ERROR and leave an error in pParse. Otherwise, populate
** pFrom->pIndex and return SQLITE_OK.
*/
int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){
if( pFrom->pTab && pFrom->zIndex ){
Table *pTab = pFrom->pTab;
char *zIndex = pFrom->zIndex;
Index *pIdx;
for(pIdx=pTab->pIndex;
pIdx && sqlite3StrICmp(pIdx->zName, zIndex);
pIdx=pIdx->pNext
);
if( !pIdx ){
sqlite3ErrorMsg(pParse, "no such index: %s", zIndex, 0);
return SQLITE_ERROR;
}
pFrom->pIndex = pIdx;
}
return SQLITE_OK;
}
/* /*
** This routine is a Walker callback for "expanding" a SELECT statement. ** This routine is a Walker callback for "expanding" a SELECT statement.
** "Expanding" means to do the following: ** "Expanding" means to do the following:
@@ -2984,19 +3009,9 @@ static int selectExpander(Walker *pWalker, Select *p){
} }
/* Locate the index named by the INDEXED BY clause, if any. */ /* Locate the index named by the INDEXED BY clause, if any. */
if( pFrom->zIndex ){ if( sqlite3IndexedByLookup(pParse, pFrom) ){
char *zIndex = pFrom->zIndex;
Index *pIdx;
for(pIdx=pTab->pIndex;
pIdx && sqlite3StrICmp(pIdx->zName, zIndex);
pIdx=pIdx->pNext
);
if( !pIdx ){
sqlite3ErrorMsg(pParse, "no such index: %s", zIndex, 0);
return WRC_Abort; return WRC_Abort;
} }
pFrom->pIndex = pIdx;
}
} }
/* Process NATURAL keywords, and ON and USING clauses of joins. /* Process NATURAL keywords, and ON and USING clauses of joins.

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.774 2008/10/06 05:32:19 danielk1977 Exp $ ** @(#) $Id: sqliteInt.h,v 1.775 2008/10/06 16:18:40 danielk1977 Exp $
*/ */
#ifndef _SQLITEINT_H_ #ifndef _SQLITEINT_H_
#define _SQLITEINT_H_ #define _SQLITEINT_H_
@@ -2141,8 +2141,10 @@ void *sqlite3ArrayAllocate(sqlite3*,void*,int,int,int*,int*,int*);
IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*); IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
int sqlite3IdListIndex(IdList*,const char*); int sqlite3IdListIndex(IdList*,const char*);
SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*); SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);
SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, Token*, SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
Token*, Select*, Expr*, IdList*); Token*, Select*, Expr*, IdList*);
void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
void sqlite3SrcListShiftJoinType(SrcList*); void sqlite3SrcListShiftJoinType(SrcList*);
void sqlite3SrcListAssignCursors(Parse*, SrcList*); void sqlite3SrcListAssignCursors(Parse*, SrcList*);
void sqlite3IdListDelete(sqlite3*, IdList*); void sqlite3IdListDelete(sqlite3*, IdList*);

View File

@@ -9,7 +9,7 @@
# #
#*********************************************************************** #***********************************************************************
# #
# $Id: indexedby.test,v 1.2 2008/10/06 11:29:49 danielk1977 Exp $ # $Id: indexedby.test,v 1.3 2008/10/06 16:18:40 danielk1977 Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@@ -162,5 +162,47 @@ do_test indexedby-6.2 {
EQP { SELECT * FROM t1 NOT INDEXED WHERE b = 10 ORDER BY rowid } EQP { SELECT * FROM t1 NOT INDEXED WHERE b = 10 ORDER BY rowid }
} {0 0 {TABLE t1 USING PRIMARY KEY ORDER BY}} } {0 0 {TABLE t1 USING PRIMARY KEY ORDER BY}}
# Test that "INDEXED BY" can be used in a DELETE statement.
#
do_test indexedby-7.1 {
EQP { DELETE FROM t1 WHERE a = 5 }
} {0 0 {TABLE t1 WITH INDEX i1}}
do_test indexedby-7.2 {
EQP { DELETE FROM t1 NOT INDEXED WHERE a = 5 }
} {0 0 {TABLE t1}}
do_test indexedby-7.3 {
EQP { DELETE FROM t1 INDEXED BY i1 WHERE a = 5 }
} {0 0 {TABLE t1 WITH INDEX i1}}
do_test indexedby-7.4 {
EQP { DELETE FROM t1 INDEXED BY i1 WHERE a = 5 AND b = 10}
} {0 0 {TABLE t1 WITH INDEX i1}}
do_test indexedby-7.5 {
EQP { DELETE FROM t1 INDEXED BY i2 WHERE a = 5 AND b = 10}
} {0 0 {TABLE t1 WITH INDEX i2}}
do_test indexedby-7.6 {
catchsql { DELETE FROM t1 INDEXED BY i2 WHERE a = 5}
} {1 {cannot use index: i2}}
# Test that "INDEXED BY" can be used in an UPDATE statement.
#
do_test indexedby-8.1 {
EQP { UPDATE t1 SET rowid=rowid+1 WHERE a = 5 }
} {0 0 {TABLE t1 WITH INDEX i1}}
do_test indexedby-8.2 {
EQP { UPDATE t1 NOT INDEXED SET rowid=rowid+1 WHERE a = 5 }
} {0 0 {TABLE t1}}
do_test indexedby-8.3 {
EQP { UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5 }
} {0 0 {TABLE t1 WITH INDEX i1}}
do_test indexedby-8.4 {
EQP { UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5 AND b = 10}
} {0 0 {TABLE t1 WITH INDEX i1}}
do_test indexedby-8.5 {
EQP { UPDATE t1 INDEXED BY i2 SET rowid=rowid+1 WHERE a = 5 AND b = 10}
} {0 0 {TABLE t1 WITH INDEX i2}}
do_test indexedby-8.6 {
catchsql { UPDATE t1 INDEXED BY i2 SET rowid=rowid+1 WHERE a = 5}
} {1 {cannot use index: i2}}
finish_test finish_test