📄 update.c
字号:
#include "eDbInit.h"
/*
** Process an UPDATE statement.
**
** UPDATE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
** \________/ \______/ \________________/
* pTabList pChanges pWhere
*/
void eDbUpdate(
Parser *pParse, /* The parser context */
SrcList *pTabList, /* The table in which we should change things */
IdExprList *pChanges, /* Things to be changed */
Expr *pWhere /* The WHERE clause. May be null */
){
int i, j; /* Loop counters */
Table *pTab; /* The table to be updated */
Index *pIdx; /* For looping over indices */
int iCur; /* VDBE Cursor number of pTab */
eDb *db; /* The database structure */
int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
** an expression for the i-th column of the table.
** aXRef[i]==-1 if the i-th column is not changed. */
int keyColumn; /* True if the record number is being changed */
int isView; /* Trying to update a view */
ExprList *pEList;
IdList *pIdList;
ParseResult *pRes = eDbMalloc(sizeof(ParseResult));
if( pParse->nErr || eDb_malloc_failed ) goto update_cleanup;
db = pParse->db;
assert( pTabList->nSrc==1 );
/* Locate the table which we want to update.
*/
pTab = eDbSrcListLookup(pParse, pTabList);
if( pTab==0 ) goto update_cleanup;
isView = pTab->pSelect!=0;
aXRef = eDbMalloc( sizeof(u8) * pTab->nCol );
if( aXRef==0 ) goto update_cleanup;
for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
/* Allocate a cursors for the main database table and for all indices.
** The index cursors might not be used, but if they are used they
** need to occur right after the database cursor. So go ahead and
** allocate enough space, just in case.
*/
pTabList->a[0].iCursor = iCur = pParse->nTab++;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
pParse->nTab++;
}
/* Resolve the column names in all the expressions of the
** of the UPDATE statement. Also find the column index
** for each column to be updated in the pChanges array.
*/
pIdList = pChanges->pIdList;
pEList = pChanges->pEList;
for(i=0; i<pEList->nExpr; i++){
if( eDbExprResolveIds(pParse, pTabList, 0, pEList->a[i].pExpr) ){
goto update_cleanup;
}
if( eDbExprCheck(pParse, pEList->a[i].pExpr, 0, 0) ){
goto update_cleanup;
}
}
for(i=0; i<pIdList->nId; i++){
pIdList->a[i].idx = -1;
}
for(i=0; i<pIdList->nId; i++){
/*find the column name in table and set its indices */
for(j=0; j<pTab->nCol; j++){
if( eDbStrICmp(pIdList->a[i].zName, pTab->aCol[j].zName)==0 ){
pIdList->a[i].idx = j;
if( j==pTab->iPKey ){
keyColumn = i;
}
break;
}
}
if( j>=pTab->nCol ){
eDbErrorMsg(pParse, "table %s has no column named %s",
pTabList->a[0].zName, 0, pIdList->a[i].zName);
pParse->nErr++;
goto update_cleanup;
}
}
/* Resolve the column names in all the expressions in the
** WHERE clause.
*/
if( pWhere ){
if( eDbExprResolveIds(pParse, pTabList, 0, pWhere) ){
goto update_cleanup;
}
if( eDbExprCheck(pParse, pWhere, 0, 0) ){
goto update_cleanup;
}
eDbDealwithWhereClause(pTabList,pWhere);
}
/* 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.
*/
else{
}
pRes->pWhere = pWhere;
pRes->pTable = pTab;
pRes->pIdList = pIdList;
pRes->pEList = pEList;
pRes->op = Op_Update;
pParse->pResult = pRes;
eDbSrcListDelete(pTabList);
return;
update_cleanup:
eDbFree(aXRef);
eDbSrcListDelete(pTabList);
eDbIdExprListDelete(pChanges);
eDbExprDelete(pWhere);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -