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

📄 delete.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** 2001 September 15**** The author disclaims copyright to this source code.  In place of** a legal notice, here is a blessing:****    May you do good and not evil.**    May you find forgiveness for yourself and forgive others.**    May you share freely, never taking more than you give.***************************************************************************** This file contains C code routines that are called by the parser** in order to generate code for DELETE FROM statements.**** $Id: delete.c,v 1.129 2007/04/16 15:06:25 danielk1977 Exp $*/#include "sqliteInt.h"/*** Look up every table that is named in pSrc.  If any table is not found,** add an error message to pParse->zErrMsg and return NULL.  If all tables** are found, return a pointer to the last table.*/Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){  Table *pTab = 0;  int i;  struct SrcList_item *pItem;  for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){    pTab = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase);    sqlite3DeleteTable(pItem->pTab);    pItem->pTab = pTab;    if( pTab ){      pTab->nRef++;    }  }  return pTab;}/*** Check to make sure the given table is writable.  If it is not** writable, generate an error message and return 1.  If it is** writable return 0;*/int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){  if( (pTab->readOnly && (pParse->db->flags & SQLITE_WriteSchema)==0        && pParse->nested==0) #ifndef SQLITE_OMIT_VIRTUALTABLE      || (pTab->pMod && pTab->pMod->pModule->xUpdate==0)#endif  ){    sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);    return 1;  }#ifndef SQLITE_OMIT_VIEW  if( !viewOk && pTab->pSelect ){    sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);    return 1;  }#endif  return 0;}/*** Generate code that will open a table for reading.*/void sqlite3OpenTable(  Parse *p,       /* Generate code into this VDBE */  int iCur,       /* The cursor number of the table */  int iDb,        /* The database index in sqlite3.aDb[] */  Table *pTab,    /* The table to be opened */  int opcode      /* OP_OpenRead or OP_OpenWrite */){  Vdbe *v;  if( IsVirtual(pTab) ) return;  v = sqlite3GetVdbe(p);  assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );  sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite), pTab->zName);  sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);  VdbeComment((v, "# %s", pTab->zName));  sqlite3VdbeAddOp(v, opcode, iCur, pTab->tnum);  sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);}/*** Generate code for a DELETE FROM statement.****     DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;**                 \________/       \________________/**                  pTabList              pWhere*/void sqlite3DeleteFrom(  Parse *pParse,         /* The parser context */  SrcList *pTabList,     /* The table from which we should delete things */  Expr *pWhere           /* The WHERE clause.  May be null */){  Vdbe *v;               /* The virtual database engine */  Table *pTab;           /* The table from which records will be deleted */  const char *zDb;       /* Name of database holding pTab */  int end, addr = 0;     /* A couple addresses of generated code */  int i;                 /* Loop counter */  WhereInfo *pWInfo;     /* Information about the WHERE clause */  Index *pIdx;           /* For looping over indices of the table */  int iCur;              /* VDBE Cursor number for pTab */  sqlite3 *db;           /* Main database structure */  AuthContext sContext;  /* Authorization context */  int oldIdx = -1;       /* Cursor for the OLD table of AFTER triggers */  NameContext sNC;       /* Name context to resolve expressions in */  int iDb;               /* Database number */  int memCnt = 0;        /* Memory cell used for change counting */#ifndef SQLITE_OMIT_TRIGGER  int isView;                  /* True if attempting to delete from a view */  int triggers_exist = 0;      /* True if any triggers exist */#endif  sContext.pParse = 0;  if( pParse->nErr || sqlite3MallocFailed() ){    goto delete_from_cleanup;  }  db = pParse->db;  assert( pTabList->nSrc==1 );  /* Locate the table which we want to delete.  This table has to be  ** put in an SrcList structure because some of the subroutines we  ** will be calling are designed to work with multiple tables and expect  ** an SrcList* parameter instead of just a Table* parameter.  */  pTab = sqlite3SrcListLookup(pParse, pTabList);  if( pTab==0 )  goto delete_from_cleanup;  /* Figure out if we have any triggers and if the table being  ** deleted from is a view  */#ifndef SQLITE_OMIT_TRIGGER  triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0);  isView = pTab->pSelect!=0;#else# define triggers_exist 0# define isView 0#endif#ifdef SQLITE_OMIT_VIEW# undef isView# define isView 0#endif  if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){    goto delete_from_cleanup;  }  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);  assert( iDb<db->nDb );  zDb = db->aDb[iDb].zName;  if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){    goto delete_from_cleanup;  }  /* If pTab is really a view, make sure it has been initialized.  */  if( sqlite3ViewGetColumnNames(pParse, pTab) ){    goto delete_from_cleanup;  }  /* Allocate a cursor used to store the old.* data for a trigger.  */  if( triggers_exist ){     oldIdx = pParse->nTab++;  }  /* Resolve the column names in the WHERE clause.  */  assert( pTabList->nSrc==1 );  iCur = pTabList->a[0].iCursor = pParse->nTab++;  memset(&sNC, 0, sizeof(sNC));  sNC.pParse = pParse;  sNC.pSrcList = pTabList;  if( sqlite3ExprResolveNames(&sNC, pWhere) ){    goto delete_from_cleanup;  }  /* Start the view context  */  if( isView ){    sqlite3AuthContextPush(pParse, &sContext, pTab->zName);  }  /* Begin generating code.  */  v = sqlite3GetVdbe(pParse);  if( v==0 ){    goto delete_from_cleanup;  }  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);  sqlite3BeginWriteOperation(pParse, triggers_exist, iDb);  /* If we are trying to delete from a view, realize that view into  ** a ephemeral table.  */  if( isView ){    Select *pView = sqlite3SelectDup(pTab->pSelect);    sqlite3Select(pParse, pView, SRT_EphemTab, iCur, 0, 0, 0, 0);    sqlite3SelectDelete(pView);  }  /* Initialize the counter of the number of rows deleted, if  ** we are counting rows.  */  if( db->flags & SQLITE_CountRows ){    memCnt = pParse->nMem++;    sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt);  }  /* Special case: A DELETE without a WHERE clause deletes everything.  ** It is easier just to erase the whole table.  Note, however, that  ** this means that the row change count will be incorrect.  */  if( pWhere==0 && !triggers_exist && !IsVirtual(pTab) ){    if( db->flags & SQLITE_CountRows ){      /* If counting rows deleted, just count the total number of      ** entries in the table. */      int endOfLoop = sqlite3VdbeMakeLabel(v);      int addr2;      if( !isView ){        sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);      }      sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);      addr2 = sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt);      sqlite3VdbeAddOp(v, OP_Next, iCur, addr2);      sqlite3VdbeResolveLabel(v, endOfLoop);      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);    }    if( !isView ){      sqlite3VdbeAddOp(v, OP_Clear, pTab->tnum, iDb);      if( !pParse->nested ){        sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);

⌨️ 快捷键说明

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