⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 delete.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 2 页
字号:
      }      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){        assert( pIdx->pSchema==pTab->pSchema );        sqlite3VdbeAddOp(v, OP_Clear, pIdx->tnum, iDb);      }    }  }   /* The usual case: There is a WHERE clause so we have to scan through  ** the table and pick which records to delete.  */  else{    /* Begin the database scan    */    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);    if( pWInfo==0 ) goto delete_from_cleanup;    /* Remember the rowid of every item to be deleted.    */    sqlite3VdbeAddOp(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, 0);    sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0);    if( db->flags & SQLITE_CountRows ){      sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt);    }    /* End the database scan loop.    */    sqlite3WhereEnd(pWInfo);    /* Open the pseudo-table used to store OLD if there are triggers.    */    if( triggers_exist ){      sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);      sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);    }    /* Delete every item whose key was written to the list during the    ** database scan.  We have to delete items after the scan is complete    ** because deleting an item can change the scan order.    */    end = sqlite3VdbeMakeLabel(v);    /* This is the beginning of the delete loop when there are    ** row triggers.    */    if( triggers_exist ){      addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);      if( !isView ){        sqlite3VdbeAddOp(v, OP_Dup, 0, 0);        sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);      }      sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);      sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);      sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);      sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);      if( !isView ){        sqlite3VdbeAddOp(v, OP_Close, iCur, 0);      }      (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab,          -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,          addr);    }    if( !isView ){      /* Open cursors for the table we are deleting from and all its      ** indices.  If there are row triggers, this happens inside the      ** OP_FifoRead loop because the cursor have to all be closed      ** before the trigger fires.  If there are no row triggers, the      ** cursors are opened only once on the outside the loop.      */      sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);      /* This is the beginning of the delete loop when there are no      ** row triggers */      if( !triggers_exist ){         addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);      }      /* Delete the row */#ifndef SQLITE_OMIT_VIRTUALTABLE      if( IsVirtual(pTab) ){        pParse->pVirtualLock = pTab;        sqlite3VdbeOp3(v, OP_VUpdate, 0, 1, (const char*)pTab->pVtab, P3_VTAB);      }else#endif      {        sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0);      }    }    /* If there are row triggers, close all cursors then invoke    ** the AFTER triggers    */    if( triggers_exist ){      if( !isView ){        for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){          sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);        }        sqlite3VdbeAddOp(v, OP_Close, iCur, 0);      }      (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1,          oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,          addr);    }    /* End of the delete loop */    sqlite3VdbeAddOp(v, OP_Goto, 0, addr);    sqlite3VdbeResolveLabel(v, end);    /* Close the cursors after the loop if there are no row triggers */    if( !triggers_exist && !IsVirtual(pTab) ){      for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){        sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);      }      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);    }  }  /*  ** Return the number of rows that were deleted. If this routine is   ** generating code because of a call to sqlite3NestedParse(), do not  ** invoke the callback function.  */  if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){    sqlite3VdbeAddOp(v, OP_MemLoad, memCnt, 0);    sqlite3VdbeAddOp(v, OP_Callback, 1, 0);    sqlite3VdbeSetNumCols(v, 1);    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", P3_STATIC);  }delete_from_cleanup:  sqlite3AuthContextPop(&sContext);  sqlite3SrcListDelete(pTabList);  sqlite3ExprDelete(pWhere);  return;}/*** This routine generates VDBE code that causes a single row of a** single table to be deleted.**** The VDBE must be in a particular state when this routine is called.** These are the requirements:****   1.  A read/write cursor pointing to pTab, the table containing the row**       to be deleted, must be opened as cursor number "base".****   2.  Read/write cursors for all indices of pTab must be open as**       cursor number base+i for the i-th index.****   3.  The record number of the row to be deleted must be on the top**       of the stack.**** This routine pops the top of the stack to remove the record number** and then generates code to remove both the table record and all index** entries that point to that record.*/void sqlite3GenerateRowDelete(  sqlite3 *db,       /* The database containing the index */  Vdbe *v,           /* Generate code into this VDBE */  Table *pTab,       /* Table containing the row to be deleted */  int iCur,          /* Cursor number for the table */  int count          /* Increment the row change counter */){  int addr;  addr = sqlite3VdbeAddOp(v, OP_NotExists, iCur, 0);  sqlite3GenerateRowIndexDelete(v, pTab, iCur, 0);  sqlite3VdbeAddOp(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));  if( count ){    sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);  }  sqlite3VdbeJumpHere(v, addr);}/*** This routine generates VDBE code that causes the deletion of all** index entries associated with a single row of a single table.**** The VDBE must be in a particular state when this routine is called.** These are the requirements:****   1.  A read/write cursor pointing to pTab, the table containing the row**       to be deleted, must be opened as cursor number "iCur".****   2.  Read/write cursors for all indices of pTab must be open as**       cursor number iCur+i for the i-th index.****   3.  The "iCur" cursor must be pointing to the row that is to be**       deleted.*/void sqlite3GenerateRowIndexDelete(  Vdbe *v,           /* Generate code into this VDBE */  Table *pTab,       /* Table containing the row to be deleted */  int iCur,          /* Cursor number for the table */  char *aIdxUsed     /* Only delete if aIdxUsed!=0 && aIdxUsed[i]!=0 */){  int i;  Index *pIdx;  for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){    if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;    sqlite3GenerateIndexKey(v, pIdx, iCur);    sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0);  }}/*** Generate code that will assemble an index key and put it on the top** of the tack.  The key with be for index pIdx which is an index on pTab.** iCur is the index of a cursor open on the pTab table and pointing to** the entry that needs indexing.*/void sqlite3GenerateIndexKey(  Vdbe *v,           /* Generate code into this VDBE */  Index *pIdx,       /* The index for which to generate a key */  int iCur           /* Cursor number for the pIdx->pTable table */){  int j;  Table *pTab = pIdx->pTable;  sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);  for(j=0; j<pIdx->nColumn; j++){    int idx = pIdx->aiColumn[j];    if( idx==pTab->iPKey ){      sqlite3VdbeAddOp(v, OP_Dup, j, 0);    }else{      sqlite3VdbeAddOp(v, OP_Column, iCur, idx);      sqlite3ColumnDefault(v, pTab, idx);    }  }  sqlite3VdbeAddOp(v, OP_MakeIdxRec, pIdx->nColumn, 0);  sqlite3IndexAffinityStr(v, pIdx);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -