1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/extensions/sqlite/sqlite-source/delete.c Sun Mar 30 07:00:22 2008 +0000
1.3 @@ -0,0 +1,467 @@
1.4 +/*
1.5 +** 2001 September 15
1.6 +**
1.7 +** The author disclaims copyright to this source code. In place of
1.8 +** a legal notice, here is a blessing:
1.9 +**
1.10 +** May you do good and not evil.
1.11 +** May you find forgiveness for yourself and forgive others.
1.12 +** May you share freely, never taking more than you give.
1.13 +**
1.14 +*************************************************************************
1.15 +** This file contains C code routines that are called by the parser
1.16 +** in order to generate code for DELETE FROM statements.
1.17 +**
1.18 +** $Id$
1.19 +*/
1.20 +#include "sqliteInt.h"
1.21 +
1.22 +/*
1.23 +** Look up every table that is named in pSrc. If any table is not found,
1.24 +** add an error message to pParse->zErrMsg and return NULL. If all tables
1.25 +** are found, return a pointer to the last table.
1.26 +*/
1.27 +Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
1.28 + Table *pTab = 0;
1.29 + int i;
1.30 + struct SrcList_item *pItem;
1.31 + for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
1.32 + pTab = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase);
1.33 + sqlite3DeleteTable(pItem->pTab);
1.34 + pItem->pTab = pTab;
1.35 + if( pTab ){
1.36 + pTab->nRef++;
1.37 + }
1.38 + }
1.39 + return pTab;
1.40 +}
1.41 +
1.42 +/*
1.43 +** Check to make sure the given table is writable. If it is not
1.44 +** writable, generate an error message and return 1. If it is
1.45 +** writable return 0;
1.46 +*/
1.47 +int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
1.48 + if( (pTab->readOnly && (pParse->db->flags & SQLITE_WriteSchema)==0
1.49 + && pParse->nested==0)
1.50 +#ifndef SQLITE_OMIT_VIRTUALTABLE
1.51 + || (pTab->pMod && pTab->pMod->pModule->xUpdate==0)
1.52 +#endif
1.53 + ){
1.54 + sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
1.55 + return 1;
1.56 + }
1.57 +#ifndef SQLITE_OMIT_VIEW
1.58 + if( !viewOk && pTab->pSelect ){
1.59 + sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
1.60 + return 1;
1.61 + }
1.62 +#endif
1.63 + return 0;
1.64 +}
1.65 +
1.66 +/*
1.67 +** Generate code that will open a table for reading.
1.68 +*/
1.69 +void sqlite3OpenTable(
1.70 + Parse *p, /* Generate code into this VDBE */
1.71 + int iCur, /* The cursor number of the table */
1.72 + int iDb, /* The database index in sqlite3.aDb[] */
1.73 + Table *pTab, /* The table to be opened */
1.74 + int opcode /* OP_OpenRead or OP_OpenWrite */
1.75 +){
1.76 + Vdbe *v;
1.77 + if( IsVirtual(pTab) ) return;
1.78 + v = sqlite3GetVdbe(p);
1.79 + assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
1.80 + sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite), pTab->zName);
1.81 + sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
1.82 + VdbeComment((v, "# %s", pTab->zName));
1.83 + sqlite3VdbeAddOp(v, opcode, iCur, pTab->tnum);
1.84 + sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
1.85 +}
1.86 +
1.87 +
1.88 +/*
1.89 +** Generate code for a DELETE FROM statement.
1.90 +**
1.91 +** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;
1.92 +** \________/ \________________/
1.93 +** pTabList pWhere
1.94 +*/
1.95 +void sqlite3DeleteFrom(
1.96 + Parse *pParse, /* The parser context */
1.97 + SrcList *pTabList, /* The table from which we should delete things */
1.98 + Expr *pWhere /* The WHERE clause. May be null */
1.99 +){
1.100 + Vdbe *v; /* The virtual database engine */
1.101 + Table *pTab; /* The table from which records will be deleted */
1.102 + const char *zDb; /* Name of database holding pTab */
1.103 + int end, addr = 0; /* A couple addresses of generated code */
1.104 + int i; /* Loop counter */
1.105 + WhereInfo *pWInfo; /* Information about the WHERE clause */
1.106 + Index *pIdx; /* For looping over indices of the table */
1.107 + int iCur; /* VDBE Cursor number for pTab */
1.108 + sqlite3 *db; /* Main database structure */
1.109 + AuthContext sContext; /* Authorization context */
1.110 + int oldIdx = -1; /* Cursor for the OLD table of AFTER triggers */
1.111 + NameContext sNC; /* Name context to resolve expressions in */
1.112 + int iDb; /* Database number */
1.113 + int memCnt = 0; /* Memory cell used for change counting */
1.114 +
1.115 +#ifndef SQLITE_OMIT_TRIGGER
1.116 + int isView; /* True if attempting to delete from a view */
1.117 + int triggers_exist = 0; /* True if any triggers exist */
1.118 +#endif
1.119 +
1.120 + sContext.pParse = 0;
1.121 + db = pParse->db;
1.122 + if( pParse->nErr || db->mallocFailed ){
1.123 + goto delete_from_cleanup;
1.124 + }
1.125 + assert( pTabList->nSrc==1 );
1.126 +
1.127 + /* Locate the table which we want to delete. This table has to be
1.128 + ** put in an SrcList structure because some of the subroutines we
1.129 + ** will be calling are designed to work with multiple tables and expect
1.130 + ** an SrcList* parameter instead of just a Table* parameter.
1.131 + */
1.132 + pTab = sqlite3SrcListLookup(pParse, pTabList);
1.133 + if( pTab==0 ) goto delete_from_cleanup;
1.134 +
1.135 + /* Figure out if we have any triggers and if the table being
1.136 + ** deleted from is a view
1.137 + */
1.138 +#ifndef SQLITE_OMIT_TRIGGER
1.139 + triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0);
1.140 + isView = pTab->pSelect!=0;
1.141 +#else
1.142 +# define triggers_exist 0
1.143 +# define isView 0
1.144 +#endif
1.145 +#ifdef SQLITE_OMIT_VIEW
1.146 +# undef isView
1.147 +# define isView 0
1.148 +#endif
1.149 +
1.150 + if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
1.151 + goto delete_from_cleanup;
1.152 + }
1.153 + iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
1.154 + assert( iDb<db->nDb );
1.155 + zDb = db->aDb[iDb].zName;
1.156 + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
1.157 + goto delete_from_cleanup;
1.158 + }
1.159 +
1.160 + /* If pTab is really a view, make sure it has been initialized.
1.161 + */
1.162 + if( sqlite3ViewGetColumnNames(pParse, pTab) ){
1.163 + goto delete_from_cleanup;
1.164 + }
1.165 +
1.166 + /* Allocate a cursor used to store the old.* data for a trigger.
1.167 + */
1.168 + if( triggers_exist ){
1.169 + oldIdx = pParse->nTab++;
1.170 + }
1.171 +
1.172 + /* Resolve the column names in the WHERE clause.
1.173 + */
1.174 + assert( pTabList->nSrc==1 );
1.175 + iCur = pTabList->a[0].iCursor = pParse->nTab++;
1.176 + memset(&sNC, 0, sizeof(sNC));
1.177 + sNC.pParse = pParse;
1.178 + sNC.pSrcList = pTabList;
1.179 + if( sqlite3ExprResolveNames(&sNC, pWhere) ){
1.180 + goto delete_from_cleanup;
1.181 + }
1.182 +
1.183 + /* Start the view context
1.184 + */
1.185 + if( isView ){
1.186 + sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
1.187 + }
1.188 +
1.189 + /* Begin generating code.
1.190 + */
1.191 + v = sqlite3GetVdbe(pParse);
1.192 + if( v==0 ){
1.193 + goto delete_from_cleanup;
1.194 + }
1.195 + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
1.196 + sqlite3BeginWriteOperation(pParse, triggers_exist, iDb);
1.197 +
1.198 + /* If we are trying to delete from a view, realize that view into
1.199 + ** a ephemeral table.
1.200 + */
1.201 + if( isView ){
1.202 + Select *pView = sqlite3SelectDup(db, pTab->pSelect);
1.203 + sqlite3Select(pParse, pView, SRT_EphemTab, iCur, 0, 0, 0, 0);
1.204 + sqlite3SelectDelete(pView);
1.205 + }
1.206 +
1.207 + /* Initialize the counter of the number of rows deleted, if
1.208 + ** we are counting rows.
1.209 + */
1.210 + if( db->flags & SQLITE_CountRows ){
1.211 + memCnt = pParse->nMem++;
1.212 + sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt);
1.213 + }
1.214 +
1.215 + /* Special case: A DELETE without a WHERE clause deletes everything.
1.216 + ** It is easier just to erase the whole table. Note, however, that
1.217 + ** this means that the row change count will be incorrect.
1.218 + */
1.219 + if( pWhere==0 && !triggers_exist && !IsVirtual(pTab) ){
1.220 + if( db->flags & SQLITE_CountRows ){
1.221 + /* If counting rows deleted, just count the total number of
1.222 + ** entries in the table. */
1.223 + int endOfLoop = sqlite3VdbeMakeLabel(v);
1.224 + int addr2;
1.225 + if( !isView ){
1.226 + sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
1.227 + }
1.228 + sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
1.229 + addr2 = sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt);
1.230 + sqlite3VdbeAddOp(v, OP_Next, iCur, addr2);
1.231 + sqlite3VdbeResolveLabel(v, endOfLoop);
1.232 + sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
1.233 + }
1.234 + if( !isView ){
1.235 + sqlite3VdbeAddOp(v, OP_Clear, pTab->tnum, iDb);
1.236 + if( !pParse->nested ){
1.237 + sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
1.238 + }
1.239 + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
1.240 + assert( pIdx->pSchema==pTab->pSchema );
1.241 + sqlite3VdbeAddOp(v, OP_Clear, pIdx->tnum, iDb);
1.242 + }
1.243 + }
1.244 + }
1.245 + /* The usual case: There is a WHERE clause so we have to scan through
1.246 + ** the table and pick which records to delete.
1.247 + */
1.248 + else{
1.249 + /* Begin the database scan
1.250 + */
1.251 + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
1.252 + if( pWInfo==0 ) goto delete_from_cleanup;
1.253 +
1.254 + /* Remember the rowid of every item to be deleted.
1.255 + */
1.256 + sqlite3VdbeAddOp(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, 0);
1.257 + sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0);
1.258 + if( db->flags & SQLITE_CountRows ){
1.259 + sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt);
1.260 + }
1.261 +
1.262 + /* End the database scan loop.
1.263 + */
1.264 + sqlite3WhereEnd(pWInfo);
1.265 +
1.266 + /* Open the pseudo-table used to store OLD if there are triggers.
1.267 + */
1.268 + if( triggers_exist ){
1.269 + sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
1.270 + sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
1.271 + }
1.272 +
1.273 + /* Delete every item whose key was written to the list during the
1.274 + ** database scan. We have to delete items after the scan is complete
1.275 + ** because deleting an item can change the scan order.
1.276 + */
1.277 + end = sqlite3VdbeMakeLabel(v);
1.278 +
1.279 + /* This is the beginning of the delete loop when there are
1.280 + ** row triggers.
1.281 + */
1.282 + if( triggers_exist ){
1.283 + addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);
1.284 + if( !isView ){
1.285 + sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
1.286 + sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
1.287 + }
1.288 + sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
1.289 + sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
1.290 + sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
1.291 + sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);
1.292 + if( !isView ){
1.293 + sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
1.294 + }
1.295 +
1.296 + (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab,
1.297 + -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
1.298 + addr);
1.299 + }
1.300 +
1.301 + if( !isView ){
1.302 + /* Open cursors for the table we are deleting from and all its
1.303 + ** indices. If there are row triggers, this happens inside the
1.304 + ** OP_FifoRead loop because the cursor have to all be closed
1.305 + ** before the trigger fires. If there are no row triggers, the
1.306 + ** cursors are opened only once on the outside the loop.
1.307 + */
1.308 + sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
1.309 +
1.310 + /* This is the beginning of the delete loop when there are no
1.311 + ** row triggers */
1.312 + if( !triggers_exist ){
1.313 + addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);
1.314 + }
1.315 +
1.316 + /* Delete the row */
1.317 +#ifndef SQLITE_OMIT_VIRTUALTABLE
1.318 + if( IsVirtual(pTab) ){
1.319 + pParse->pVirtualLock = pTab;
1.320 + sqlite3VdbeOp3(v, OP_VUpdate, 0, 1, (const char*)pTab->pVtab, P3_VTAB);
1.321 + }else
1.322 +#endif
1.323 + {
1.324 + sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0);
1.325 + }
1.326 + }
1.327 +
1.328 + /* If there are row triggers, close all cursors then invoke
1.329 + ** the AFTER triggers
1.330 + */
1.331 + if( triggers_exist ){
1.332 + if( !isView ){
1.333 + for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
1.334 + sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
1.335 + }
1.336 + sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
1.337 + }
1.338 + (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1,
1.339 + oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
1.340 + addr);
1.341 + }
1.342 +
1.343 + /* End of the delete loop */
1.344 + sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
1.345 + sqlite3VdbeResolveLabel(v, end);
1.346 +
1.347 + /* Close the cursors after the loop if there are no row triggers */
1.348 + if( !triggers_exist && !IsVirtual(pTab) ){
1.349 + for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
1.350 + sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
1.351 + }
1.352 + sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
1.353 + }
1.354 + }
1.355 +
1.356 + /*
1.357 + ** Return the number of rows that were deleted. If this routine is
1.358 + ** generating code because of a call to sqlite3NestedParse(), do not
1.359 + ** invoke the callback function.
1.360 + */
1.361 + if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
1.362 + sqlite3VdbeAddOp(v, OP_MemLoad, memCnt, 0);
1.363 + sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
1.364 + sqlite3VdbeSetNumCols(v, 1);
1.365 + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", P3_STATIC);
1.366 + }
1.367 +
1.368 +delete_from_cleanup:
1.369 + sqlite3AuthContextPop(&sContext);
1.370 + sqlite3SrcListDelete(pTabList);
1.371 + sqlite3ExprDelete(pWhere);
1.372 + return;
1.373 +}
1.374 +
1.375 +/*
1.376 +** This routine generates VDBE code that causes a single row of a
1.377 +** single table to be deleted.
1.378 +**
1.379 +** The VDBE must be in a particular state when this routine is called.
1.380 +** These are the requirements:
1.381 +**
1.382 +** 1. A read/write cursor pointing to pTab, the table containing the row
1.383 +** to be deleted, must be opened as cursor number "base".
1.384 +**
1.385 +** 2. Read/write cursors for all indices of pTab must be open as
1.386 +** cursor number base+i for the i-th index.
1.387 +**
1.388 +** 3. The record number of the row to be deleted must be on the top
1.389 +** of the stack.
1.390 +**
1.391 +** This routine pops the top of the stack to remove the record number
1.392 +** and then generates code to remove both the table record and all index
1.393 +** entries that point to that record.
1.394 +*/
1.395 +void sqlite3GenerateRowDelete(
1.396 + sqlite3 *db, /* The database containing the index */
1.397 + Vdbe *v, /* Generate code into this VDBE */
1.398 + Table *pTab, /* Table containing the row to be deleted */
1.399 + int iCur, /* Cursor number for the table */
1.400 + int count /* Increment the row change counter */
1.401 +){
1.402 + int addr;
1.403 + addr = sqlite3VdbeAddOp(v, OP_NotExists, iCur, 0);
1.404 + sqlite3GenerateRowIndexDelete(v, pTab, iCur, 0);
1.405 + sqlite3VdbeAddOp(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
1.406 + if( count ){
1.407 + sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
1.408 + }
1.409 + sqlite3VdbeJumpHere(v, addr);
1.410 +}
1.411 +
1.412 +/*
1.413 +** This routine generates VDBE code that causes the deletion of all
1.414 +** index entries associated with a single row of a single table.
1.415 +**
1.416 +** The VDBE must be in a particular state when this routine is called.
1.417 +** These are the requirements:
1.418 +**
1.419 +** 1. A read/write cursor pointing to pTab, the table containing the row
1.420 +** to be deleted, must be opened as cursor number "iCur".
1.421 +**
1.422 +** 2. Read/write cursors for all indices of pTab must be open as
1.423 +** cursor number iCur+i for the i-th index.
1.424 +**
1.425 +** 3. The "iCur" cursor must be pointing to the row that is to be
1.426 +** deleted.
1.427 +*/
1.428 +void sqlite3GenerateRowIndexDelete(
1.429 + Vdbe *v, /* Generate code into this VDBE */
1.430 + Table *pTab, /* Table containing the row to be deleted */
1.431 + int iCur, /* Cursor number for the table */
1.432 + char *aIdxUsed /* Only delete if aIdxUsed!=0 && aIdxUsed[i]!=0 */
1.433 +){
1.434 + int i;
1.435 + Index *pIdx;
1.436 +
1.437 + for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
1.438 + if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;
1.439 + sqlite3GenerateIndexKey(v, pIdx, iCur);
1.440 + sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0);
1.441 + }
1.442 +}
1.443 +
1.444 +/*
1.445 +** Generate code that will assemble an index key and put it on the top
1.446 +** of the tack. The key with be for index pIdx which is an index on pTab.
1.447 +** iCur is the index of a cursor open on the pTab table and pointing to
1.448 +** the entry that needs indexing.
1.449 +*/
1.450 +void sqlite3GenerateIndexKey(
1.451 + Vdbe *v, /* Generate code into this VDBE */
1.452 + Index *pIdx, /* The index for which to generate a key */
1.453 + int iCur /* Cursor number for the pIdx->pTable table */
1.454 +){
1.455 + int j;
1.456 + Table *pTab = pIdx->pTable;
1.457 +
1.458 + sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
1.459 + for(j=0; j<pIdx->nColumn; j++){
1.460 + int idx = pIdx->aiColumn[j];
1.461 + if( idx==pTab->iPKey ){
1.462 + sqlite3VdbeAddOp(v, OP_Dup, j, 0);
1.463 + }else{
1.464 + sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
1.465 + sqlite3ColumnDefault(v, pTab, idx);
1.466 + }
1.467 + }
1.468 + sqlite3VdbeAddOp(v, OP_MakeIdxRec, pIdx->nColumn, 0);
1.469 + sqlite3IndexAffinityStr(v, pIdx);
1.470 +}