2N/A#
pragma ident "%Z%%M% %I% %E% SMI" 2N/A** The author disclaims copyright to this source code. In place of 2N/A** a legal notice, here is a blessing: 2N/A** May you do good and not evil. 2N/A** May you find forgiveness for yourself and forgive others. 2N/A** May you share freely, never taking more than you give. 2N/A************************************************************************* 2N/A** This file contains C code routines that are called by the parser 2N/A** to handle DELETE FROM statements. 2N/A** Look up every table that is named in pSrc. If any table is not found, 2N/A** add an error message to pParse->zErrMsg and return NULL. If all tables 2N/A** are found, return a pointer to the last table. 2N/A** Check to make sure the given table is writable. If it is not 2N/A** writable, generate an error message and return 1. If it is 2N/A** writable return 0; 2N/A** Process a DELETE FROM statement. 2N/A Vdbe *v;
/* The virtual database engine */ 2N/A Table *
pTab;
/* The table from which records will be deleted */ 2N/A const char *
zDb;
/* Name of database holding pTab */ 2N/A int end,
addr;
/* A couple addresses of generated code */ 2N/A int i;
/* Loop counter */ 2N/A int iCur;
/* VDBE Cursor number for pTab */ 2N/A int isView;
/* True if attempting to delete from a view */ 2N/A int oldIdx = -
1;
/* Cursor for the OLD table of AFTER triggers */ 2N/A /* Locate the table which we want to delete. This table has to be 2N/A ** put in an SrcList structure because some of the subroutines we 2N/A ** will be calling are designed to work with multiple tables and expect 2N/A ** an SrcList* parameter instead of just a Table* parameter. 2N/A /* If pTab is really a view, make sure it has been initialized. 2N/A /* Allocate a cursor used to store the old.* data for a trigger. 2N/A /* Resolve the column names in all the expressions. 2N/A /* Start the view context 2N/A /* Begin generating code. 2N/A /* If we are trying to delete from a view, construct that view into 2N/A ** a temporary table. 2N/A /* Initialize the counter of the number of rows deleted, if 2N/A ** we are counting rows. 2N/A /* Special case: A DELETE without a WHERE clause deletes everything. 2N/A ** It is easier just to erase the whole table. Note, however, that 2N/A ** this means that the row change count will be incorrect. 2N/A /* If counting rows deleted, just count the total number of 2N/A ** entries in the table. */ 2N/A /* The usual case: There is a WHERE clause so we have to scan through 2N/A ** the table and pick which records to delete. 2N/A /* Begin the database scan 2N/A /* Remember the key of every item to be deleted. 2N/A /* End the database scan loop. 2N/A /* Open the pseudo-table used to store OLD if there are triggers. 2N/A /* Delete every item whose key was written to the list during the 2N/A ** database scan. We have to delete items after the scan is complete 2N/A ** because deleting an item can change the scan order. 2N/A /* This is the beginning of the delete loop when there are 2N/A /* Open cursors for the table we are deleting from and all its 2N/A ** indices. If there are row triggers, this happens inside the 2N/A ** OP_ListRead loop because the cursor have to all be closed 2N/A ** before the trigger fires. If there are no row triggers, the 2N/A ** cursors are opened only once on the outside the loop. 2N/A /* This is the beginning of the delete loop when there are no 2N/A /* Delete the row */ 2N/A /* If there are row triggers, close all cursors then invoke 2N/A ** the AFTER triggers 2N/A /* End of the delete loop */ 2N/A /* Close the cursors after the loop if there are no row triggers */ 2N/A ** Return the number of rows that were deleted. 2N/A** This routine generates VDBE code that causes a single row of a 2N/A** single table to be deleted. 2N/A** The VDBE must be in a particular state when this routine is called. 2N/A** These are the requirements: 2N/A** 1. A read/write cursor pointing to pTab, the table containing the row 2N/A** to be deleted, must be opened as cursor number "base". 2N/A** 2. Read/write cursors for all indices of pTab must be open as 2N/A** cursor number base+i for the i-th index. 2N/A** 3. The record number of the row to be deleted must be on the top 2N/A** This routine pops the top of the stack to remove the record number 2N/A** and then generates code to remove both the table record and all index 2N/A** entries that point to that record. 2N/A Vdbe *v,
/* Generate code into this VDBE */ 2N/A int iCur,
/* Cursor number for the table */ 2N/A int count /* Increment the row change counter */ 2N/A** This routine generates VDBE code that causes the deletion of all 2N/A** index entries associated with a single row of a single table. 2N/A** The VDBE must be in a particular state when this routine is called. 2N/A** These are the requirements: 2N/A** 1. A read/write cursor pointing to pTab, the table containing the row 2N/A** to be deleted, must be opened as cursor number "iCur". 2N/A** 2. Read/write cursors for all indices of pTab must be open as 2N/A** cursor number iCur+i for the i-th index. 2N/A** 3. The "iCur" cursor must be pointing to the row that is to be 2N/A Vdbe *v,
/* Generate code into this VDBE */ 2N/A int iCur,
/* Cursor number for the table */ 2N/A char *
aIdxUsed /* Only delete if aIdxUsed!=0 && aIdxUsed[i]!=0 */