1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Updated LIMIT support for DELETE/UPDATE. Omit option changed to SQLITE_ENABLE_UPDATE_DELETE_LIMIT. (CVS 5788)

FossilOrigin-Name: c10e8a3c7ab7f21c95f24d0aba590f5b18a4b028
This commit is contained in:
shane
2008-10-10 04:34:16 +00:00
parent 510f96590b
commit 273f619b58
7 changed files with 74 additions and 37 deletions

View File

@ -1,5 +1,5 @@
C Fix\san\sassert()\sfailure\sthat\scan\soccur\sif\sthe\suser\sattempts\sto\sset\san\sinto\san\sinteger\sprimary\skey\scolumn\sto\sa\stext\svalue\sin\sa\stable\sthat\shas\sa\sBEFORE\sUPDATE\strigger.\s(CVS\s5787) C Updated\sLIMIT\ssupport\sfor\sDELETE/UPDATE.\s\sOmit\soption\schanged\sto\sSQLITE_ENABLE_UPDATE_DELETE_LIMIT.\s(CVS\s5788)
D 2008-10-09T18:48:31 D 2008-10-10T04:34:16
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 7fc26e087207e7a4a7723583dbd7997477af3b13 F Makefile.in 7fc26e087207e7a4a7723583dbd7997477af3b13
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -106,7 +106,7 @@ 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 1b1fc801df40aae891bff8b03f65313df192d677 F src/date.c 1b1fc801df40aae891bff8b03f65313df192d677
F src/delete.c 7c9183a17b93b79dabbbc7cdb2159972d052b5a0 F src/delete.c 24d4f58280bb0717c3eee8ff613d1b3200f101e3
F src/expr.c 0ceafeff3a4e0f460d6a7695a675ae12391e313d F src/expr.c 0ceafeff3a4e0f460d6a7695a675ae12391e313d
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
F src/func.c 8431b40a7843d1024145684d303c55b4ee087bbe F src/func.c 8431b40a7843d1024145684d303c55b4ee087bbe
@ -140,19 +140,19 @@ F src/os_unix.c f33b69d8a85372b270fe37ee664a4c2140a5217d
F src/os_win.c 04033a86a39f49cb8e348f515eb0116aa9d36678 F src/os_win.c 04033a86a39f49cb8e348f515eb0116aa9d36678
F src/pager.c d98f56128e849083f2f612196efebd982c491fea F src/pager.c d98f56128e849083f2f612196efebd982c491fea
F src/pager.h 9c1917be28fff58118e1fe0ddbc7adfb8dd4f44d F src/pager.h 9c1917be28fff58118e1fe0ddbc7adfb8dd4f44d
F src/parse.y 85d57c1dba3098da736a0c2ff8917c3d02a3a5f8 F src/parse.y ecabcd6402a611a223824291b8b4e026c622c2b3
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
F src/prepare.c c7e00ed1b0bdcf699b1aad651247d4dc3d281b0b F src/prepare.c c7e00ed1b0bdcf699b1aad651247d4dc3d281b0b
F src/printf.c 785f87120589c1db672e37c6eb1087c456e6f84d F src/printf.c 785f87120589c1db672e37c6eb1087c456e6f84d
F src/random.c a87afbd598aa877e23ac676ee92fd8ee5c786a51 F src/random.c a87afbd598aa877e23ac676ee92fd8ee5c786a51
F src/resolve.c 1971ff6996f1a73303339acf7f1de8497546045d F src/resolve.c d45e7b69f9ff653799384d7fcdd0c8d7096908b7
F src/select.c d910d7350df0d918e22286c5bfd39d4ea68ec813 F src/select.c d910d7350df0d918e22286c5bfd39d4ea68ec813
F src/shell.c d83b578a8ccdd3e0e7fef4388a0887ce9f810967 F src/shell.c d83b578a8ccdd3e0e7fef4388a0887ce9f810967
F src/sqlite.h.in f2640167eca2e9273ec5ea97b37155344290bd2a F src/sqlite.h.in f2640167eca2e9273ec5ea97b37155344290bd2a
F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e F src/sqlite3ext.h 1e3887c9bd3ae66cb599e922824b04cd0d0f2c3e
F src/sqliteInt.h 3f38b600c978698014fdda68d29ca5f3792ad717 F src/sqliteInt.h 0da9c664d89995d28587548048837e3063fa0be3
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
@ -169,7 +169,7 @@ F src/test9.c 904ebe0ed1472d6bad17a81e2ecbfc20017dc237
F src/test_async.c 45024094ed7cf780c5d5dccda645145f95cf78ef F src/test_async.c 45024094ed7cf780c5d5dccda645145f95cf78ef
F src/test_autoext.c f53b0cdf7bf5f08100009572a5d65cdb540bd0ad F src/test_autoext.c f53b0cdf7bf5f08100009572a5d65cdb540bd0ad
F src/test_btree.c d7b8716544611c323860370ee364e897c861f1b0 F src/test_btree.c d7b8716544611c323860370ee364e897c861f1b0
F src/test_config.c f995f649dc2dc8173079d613694b29b0b3b5f84b F src/test_config.c e5d6390729f0c63333ebe7e5927c07e50bc9deea
F src/test_devsym.c 802d10e65b4217208cb47059b84adf46318bcdf4 F src/test_devsym.c 802d10e65b4217208cb47059b84adf46318bcdf4
F src/test_func.c a55c4d5479ff2eb5c0a22d4d88e9528ab59c953b F src/test_func.c a55c4d5479ff2eb5c0a22d4d88e9528ab59c953b
F src/test_hexio.c 2f1122aa3f012fa0142ee3c36ce5c902a70cd12f F src/test_hexio.c 2f1122aa3f012fa0142ee3c36ce5c902a70cd12f
@ -643,7 +643,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P 2d427746d53104ca032c404f7f65c51b41b7a20e P c2cf9d60d6626844193b008a37e4417aa0a0f323
R 7a5ac900e19ad3409dae5bcb06b20f5a R dbb64f376591fe1fef8fc7d76b6610d5
U danielk1977 U shane
Z 0940f286acf7bb42a4ff023aeb3c8678 Z b0043e2235752f0517ee1d3e5441bcb7

View File

@ -1 +1 @@
c2cf9d60d6626844193b008a37e4417aa0a0f323 c10e8a3c7ab7f21c95f24d0aba590f5b18a4b028

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.178 2008/10/07 05:27:11 shane Exp $ ** $Id: delete.c,v 1.179 2008/10/10 04:34:16 shane Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@ -116,7 +116,7 @@ void sqlite3MaterializeView(
} }
#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */ #endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
#ifndef SQLITE_OMIT_UPDATE_DELETE_LIMIT #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
/* /*
** Generate an expression tree to implement the WHERE, ORDER BY, ** Generate an expression tree to implement the WHERE, ORDER BY,
** and LIMIT/OFFSET portion of DELETE and UPDATE statements. ** and LIMIT/OFFSET portion of DELETE and UPDATE statements.
@ -133,17 +133,48 @@ Expr *sqlite3LimitWhere(
Expr *pLimit, /* The LIMIT clause. May be null */ Expr *pLimit, /* The LIMIT clause. May be null */
Expr *pOffset /* The OFFSET clause. May be null */ Expr *pOffset /* The OFFSET clause. May be null */
){ ){
Expr *pWhereRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0); Expr *pWhereRowid = NULL;
Expr *pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0); Expr *pInClause = NULL;
Expr *pSelectRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0); Expr *pSelectRowid = NULL;
ExprList *pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid, 0); ExprList *pEList = NULL;
SrcList *pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc); SrcList *pSelectSrc = NULL;
Select *pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,pOrderBy,0,pLimit,pOffset); Select *pSelect = NULL;
if( pSelect ) {
pInClause->pSelect = pSelect; /* We only need to generate a select expression if there
sqlite3ExprSetHeight(pParse, pInClause); ** is a limit/offset term to enforce.
return pInClause; */
} if (!pLimit && !pOffset) return pWhere;
/* Generate a select expression tree to enforce the limit/offset
** term for the DELETE or UPDATE statement. For example:
** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
** becomes:
** DELETE FROM table_a WHERE rowid IN (
** DELETE rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
** );
*/
pSelectRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0);
if( pSelectRowid == 0 ) goto limit_where_cleanup;
pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid, 0);
if( pEList == 0 ) goto limit_where_cleanup;
/* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
** and the DELETE tree. */
pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc);
if( pSelectSrc == 0 ) goto limit_where_cleanup;
/* generate the DELETE expression tree. */
pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,pOrderBy,0,pLimit,pOffset);
if( pSelect == 0 ) goto limit_where_cleanup;
/* generate the WHERE rowid IN ( select ) expression */
pWhereRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0);
if( pWhereRowid == 0 ) goto limit_where_cleanup;
pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
if( pInClause == 0 ) goto limit_where_cleanup;
pInClause->pSelect = pSelect;
sqlite3ExprSetHeight(pParse, pInClause);
return pInClause;
limit_where_cleanup:
/* something went wrong. clean up anything allocated. */
sqlite3SrcListDelete(pParse->db, pSelectSrc); sqlite3SrcListDelete(pParse->db, pSelectSrc);
sqlite3ExprListDelete(pParse->db, pEList); sqlite3ExprListDelete(pParse->db, pEList);
sqlite3ExprDelete(pParse->db, pSelectRowid); sqlite3ExprDelete(pParse->db, pSelectRowid);
@ -151,7 +182,7 @@ Expr *sqlite3LimitWhere(
sqlite3ExprDelete(pParse->db, pWhereRowid); sqlite3ExprDelete(pParse->db, pWhereRowid);
return 0; return 0;
} }
#endif /* !defined(SQLITE_OMIT_UPDATE_DELETE_LIMIT) */ #endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
/* /*
** Generate code for a DELETE FROM statement. ** Generate code for a DELETE FROM statement.

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.255 2008/10/07 05:27:11 shane Exp $ ** @(#) $Id: parse.y,v 1.256 2008/10/10 04:34:16 shane 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_"
@ -578,7 +578,7 @@ limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y).
/////////////////////////// The DELETE statement ///////////////////////////// /////////////////////////// The DELETE statement /////////////////////////////
// //
%ifndef SQLITE_OMIT_UPDATE_DELETE_LIMIT %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
cmd ::= DELETE FROM fullname(X) indexed_opt(I) where_opt(W) orderby_opt(O) limit_opt(L). { cmd ::= DELETE FROM fullname(X) indexed_opt(I) where_opt(W) orderby_opt(O) limit_opt(L). {
sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3SrcListIndexedBy(pParse, X, &I);
if( O && !L.pLimit ){ if( O && !L.pLimit ){
@ -594,7 +594,7 @@ cmd ::= DELETE FROM fullname(X) indexed_opt(I) where_opt(W) orderby_opt(O) limit
} }
} }
%endif %endif
%ifdef SQLITE_OMIT_UPDATE_DELETE_LIMIT %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
cmd ::= DELETE FROM fullname(X) indexed_opt(I) where_opt(W). { cmd ::= DELETE FROM fullname(X) indexed_opt(I) where_opt(W). {
sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3SrcListIndexedBy(pParse, X, &I);
sqlite3DeleteFrom(pParse,X,W); sqlite3DeleteFrom(pParse,X,W);
@ -609,7 +609,7 @@ where_opt(A) ::= WHERE expr(X). {A = X;}
////////////////////////// The UPDATE command //////////////////////////////// ////////////////////////// The UPDATE command ////////////////////////////////
// //
%ifndef SQLITE_OMIT_UPDATE_DELETE_LIMIT %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
cmd ::= UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(W) orderby_opt(O) limit_opt(L). { cmd ::= UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(W) orderby_opt(O) limit_opt(L). {
sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3SrcListIndexedBy(pParse, X, &I);
sqlite3ExprListCheckLength(pParse,Y,"set list"); sqlite3ExprListCheckLength(pParse,Y,"set list");
@ -626,7 +626,7 @@ cmd ::= UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(W)
} }
} }
%endif %endif
%ifdef SQLITE_OMIT_UPDATE_DELETE_LIMIT %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
cmd ::= UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(W). { cmd ::= UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) where_opt(W). {
sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3SrcListIndexedBy(pParse, X, &I);
sqlite3ExprListCheckLength(pParse,Y,"set list"); sqlite3ExprListCheckLength(pParse,Y,"set list");

View File

@ -14,7 +14,7 @@
** resolve all identifiers by associating them with a particular ** resolve all identifiers by associating them with a particular
** table and column. ** table and column.
** **
** $Id: resolve.c,v 1.7 2008/10/06 15:18:02 drh Exp $ ** $Id: resolve.c,v 1.8 2008/10/10 04:34:16 shane Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <stdlib.h> #include <stdlib.h>
@ -419,7 +419,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
#endif #endif
switch( pExpr->op ){ switch( pExpr->op ){
#ifndef SQLITE_OMIT_UPDATE_DELETE_LIMIT #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
/* The special operator TK_ROW means use the rowid for the first /* The special operator TK_ROW means use the rowid for the first
** column in the FROM clause. This is used by the LIMIT and ORDER BY ** column in the FROM clause. This is used by the LIMIT and ORDER BY
** clause processing on UPDATE and DELETE statements. ** clause processing on UPDATE and DELETE statements.
@ -436,7 +436,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pExpr->affinity = SQLITE_AFF_INTEGER; pExpr->affinity = SQLITE_AFF_INTEGER;
break; break;
} }
#endif /* SQLITE_OMIT_UPDATE_DELETE_LIMIT */ #endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
/* A lone identifier is the name of a column. /* A lone identifier is the name of a column.
*/ */

View File

@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.779 2008/10/07 23:46:38 drh Exp $ ** @(#) $Id: sqliteInt.h,v 1.780 2008/10/10 04:34:16 shane Exp $
*/ */
#ifndef _SQLITEINT_H_ #ifndef _SQLITEINT_H_
#define _SQLITEINT_H_ #define _SQLITEINT_H_
@ -2161,7 +2161,7 @@ void sqlite3SelectDelete(sqlite3*, Select*);
Table *sqlite3SrcListLookup(Parse*, SrcList*); Table *sqlite3SrcListLookup(Parse*, SrcList*);
int sqlite3IsReadOnly(Parse*, Table*, int); int sqlite3IsReadOnly(Parse*, Table*, int);
void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
#ifndef SQLITE_OMIT_UPDATE_DELETE_LIMIT #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *); Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *);
#endif #endif
void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);

View File

@ -16,7 +16,7 @@
** The focus of this file is providing the TCL testing layer ** The focus of this file is providing the TCL testing layer
** access to compile-time constants. ** access to compile-time constants.
** **
** $Id: test_config.c,v 1.38 2008/10/07 15:25:49 drh Exp $ ** $Id: test_config.c,v 1.39 2008/10/10 04:34:16 shane Exp $
*/ */
#include "sqliteLimit.h" #include "sqliteLimit.h"
@ -450,6 +450,12 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
Tcl_SetVar2(interp, "sqlite_options", "wsd", "1", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "sqlite_options", "wsd", "1", TCL_GLOBAL_ONLY);
#endif #endif
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
Tcl_SetVar2(interp, "sqlite_options", "update_delete_limit", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "update_delete_limit", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_SECURE_DELETE #ifdef SQLITE_SECURE_DELETE
Tcl_SetVar2(interp, "sqlite_options", "secure_delete", "1", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "sqlite_options", "secure_delete", "1", TCL_GLOBAL_ONLY);
#else #else