mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-14 00:22:38 +03:00
(no comment)
FossilOrigin-Name: e272dc2b1c0edab59a40f32c77c81a3e636937280524161eff5669cb0046ad84
This commit is contained in:
82
src/alter.c
82
src/alter.c
@@ -982,6 +982,10 @@ static int renameColumnSelectCb(Walker *pWalker, Select *p){
|
||||
*/
|
||||
static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){
|
||||
RenameCtx *p = pWalker->u.pRename;
|
||||
if( pExpr->op==TK_TRIGGER && pExpr->iColumn==p->iCol ){
|
||||
renameTokenFind(pWalker->pParse, p, (void*)pExpr);
|
||||
}else
|
||||
|
||||
if( p->zOld && pExpr->op==TK_DOT ){
|
||||
Expr *pLeft = pExpr->pLeft;
|
||||
Expr *pRight = pExpr->pRight;
|
||||
@@ -1145,7 +1149,7 @@ static void renameColumnFunc(
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3WalkSelect(&sWalker, pSelect);
|
||||
}else if( rc==SQLITE_ERROR ){
|
||||
/* Failed to resolve all symboles in the view. This is not an
|
||||
/* Failed to resolve all symbols in the view. This is not an
|
||||
** error, but it will not be edited. */
|
||||
sqlite3DbFree(db, sParse.zErrMsg);
|
||||
sParse.zErrMsg = 0;
|
||||
@@ -1187,9 +1191,69 @@ static void renameColumnFunc(
|
||||
sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr);
|
||||
sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere);
|
||||
}else{
|
||||
sCtx.zOld = zOld;
|
||||
sqlite3WalkExpr(&sWalker, sParse.pNewTrigger->pWhen);
|
||||
if( sParse.pNewTrigger->pColumns ){
|
||||
/* A trigger */
|
||||
TriggerStep *pStep;
|
||||
NameContext sNC;
|
||||
memset(&sNC, 0, sizeof(sNC));
|
||||
sNC.pParse = &sParse;
|
||||
sParse.pTriggerTab = pTab;
|
||||
sParse.eTriggerOp = sParse.pNewTrigger->op;
|
||||
|
||||
/* Resolve symbols in WHEN clause */
|
||||
if( sParse.pTriggerTab==pTab && sParse.pNewTrigger->pWhen ){
|
||||
rc = sqlite3ResolveExprNames(&sNC, sParse.pNewTrigger->pWhen);
|
||||
}
|
||||
|
||||
for(pStep=sParse.pNewTrigger->step_list;
|
||||
rc==SQLITE_OK && pStep;
|
||||
pStep=pStep->pNext
|
||||
){
|
||||
if( pStep->pSelect ) sqlite3SelectPrep(&sParse, pStep->pSelect, &sNC);
|
||||
if( pStep->zTarget ){
|
||||
Table *pTarget = sqlite3FindTable(db, pStep->zTarget, zDb);
|
||||
if( pTarget==0 ){
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
SrcList sSrc;
|
||||
memset(&sSrc, 0, sizeof(sSrc));
|
||||
sSrc.nSrc = 1;
|
||||
sSrc.a[0].zName = pStep->zTarget;
|
||||
sSrc.a[0].pTab = pTarget;
|
||||
sNC.pSrcList = &sSrc;
|
||||
if( pStep->pWhere ){
|
||||
rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList);
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK && pTarget==pTab ){
|
||||
if( pStep->pIdList ){
|
||||
for(i=0; i<pStep->pIdList->nId; i++){
|
||||
char *zName = pStep->pIdList->a[i].zName;
|
||||
if( 0==sqlite3_stricmp(zName, zOld) ){
|
||||
renameTokenFind(&sParse, &sCtx, (void*)zName);
|
||||
}
|
||||
}
|
||||
}
|
||||
if( pStep->op==TK_UPDATE ){
|
||||
assert( pStep->pExprList );
|
||||
for(i=0; i<pStep->pExprList->nExpr; i++){
|
||||
char *zName = pStep->pExprList->a[i].zName;
|
||||
if( 0==sqlite3_stricmp(zName, zOld) ){
|
||||
renameTokenFind(&sParse, &sCtx, (void*)zName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
|
||||
|
||||
/* Find tokens to edit in UPDATE OF clause */
|
||||
if( sParse.pTriggerTab==pTab && sParse.pNewTrigger->pColumns ){
|
||||
for(i=0; i<sParse.pNewTrigger->pColumns->nId; i++){
|
||||
char *zName = sParse.pNewTrigger->pColumns->a[i].zName;
|
||||
if( 0==sqlite3_stricmp(zName, zOld) ){
|
||||
@@ -1197,6 +1261,16 @@ static void renameColumnFunc(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Find tokens to edit in WHEN clause */
|
||||
sqlite3WalkExpr(&sWalker, sParse.pNewTrigger->pWhen);
|
||||
|
||||
/* Find tokens to edit in trigger steps */
|
||||
for(pStep=sParse.pNewTrigger->step_list; pStep; pStep=pStep->pNext){
|
||||
sqlite3WalkSelect(&sWalker, pStep->pSelect);
|
||||
sqlite3WalkExpr(&sWalker, pStep->pWhere);
|
||||
sqlite3WalkExprList(&sWalker, pStep->pExprList);
|
||||
}
|
||||
}
|
||||
|
||||
assert( rc==SQLITE_OK );
|
||||
|
||||
@@ -1666,6 +1666,9 @@ void sqlite3ExprListSetName(
|
||||
assert( pItem->zName==0 );
|
||||
pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
|
||||
if( dequote ) sqlite3Dequote(pItem->zName);
|
||||
if( IN_RENAME_COLUMN ){
|
||||
sqlite3RenameToken(pParse, (void*)pItem->zName, pName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1451,16 +1451,16 @@ tridxby ::= NOT INDEXED. {
|
||||
// UPDATE
|
||||
trigger_cmd(A) ::=
|
||||
UPDATE(B) orconf(R) trnm(X) tridxby SET setlist(Y) where_opt(Z) scanpt(E).
|
||||
{A = sqlite3TriggerUpdateStep(pParse->db, &X, Y, Z, R, B.z, E);}
|
||||
{A = sqlite3TriggerUpdateStep(pParse, &X, Y, Z, R, B.z, E);}
|
||||
|
||||
// INSERT
|
||||
trigger_cmd(A) ::= scanpt(B) insert_cmd(R) INTO
|
||||
trnm(X) idlist_opt(F) select(S) upsert(U) scanpt(Z). {
|
||||
A = sqlite3TriggerInsertStep(pParse->db,&X,F,S,R,U,B,Z);/*A-overwrites-R*/
|
||||
A = sqlite3TriggerInsertStep(pParse,&X,F,S,R,U,B,Z);/*A-overwrites-R*/
|
||||
}
|
||||
// DELETE
|
||||
trigger_cmd(A) ::= DELETE(B) FROM trnm(X) tridxby where_opt(Y) scanpt(E).
|
||||
{A = sqlite3TriggerDeleteStep(pParse->db, &X, Y, B.z, E);}
|
||||
{A = sqlite3TriggerDeleteStep(pParse, &X, Y, B.z, E);}
|
||||
|
||||
// SELECT
|
||||
trigger_cmd(A) ::= scanpt(B) select(X) scanpt(E).
|
||||
|
||||
@@ -4049,12 +4049,12 @@ void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int);
|
||||
void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
|
||||
TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*,
|
||||
const char*,const char*);
|
||||
TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
|
||||
TriggerStep *sqlite3TriggerInsertStep(Parse*,Token*, IdList*,
|
||||
Select*,u8,Upsert*,
|
||||
const char*,const char*);
|
||||
TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8,
|
||||
TriggerStep *sqlite3TriggerUpdateStep(Parse*,Token*,ExprList*, Expr*, u8,
|
||||
const char*,const char*);
|
||||
TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*,
|
||||
TriggerStep *sqlite3TriggerDeleteStep(Parse*,Token*, Expr*,
|
||||
const char*,const char*);
|
||||
void sqlite3DeleteTrigger(sqlite3*, Trigger*);
|
||||
void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
|
||||
|
||||
@@ -428,7 +428,7 @@ static TriggerStep *triggerStepAllocate(
|
||||
** body of a trigger.
|
||||
*/
|
||||
TriggerStep *sqlite3TriggerInsertStep(
|
||||
sqlite3 *db, /* The database connection */
|
||||
Parse *pParse, /* Parser */
|
||||
Token *pTableName, /* Name of the table into which we insert */
|
||||
IdList *pColumn, /* List of columns in pTableName to insert into */
|
||||
Select *pSelect, /* A SELECT statement that supplies values */
|
||||
@@ -437,13 +437,19 @@ TriggerStep *sqlite3TriggerInsertStep(
|
||||
const char *zStart, /* Start of SQL text */
|
||||
const char *zEnd /* End of SQL text */
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
TriggerStep *pTriggerStep;
|
||||
|
||||
assert(pSelect != 0 || db->mallocFailed);
|
||||
|
||||
pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName, zStart, zEnd);
|
||||
if( pTriggerStep ){
|
||||
pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
|
||||
if( IN_RENAME_COLUMN ){
|
||||
pTriggerStep->pSelect = pSelect;
|
||||
pSelect = 0;
|
||||
}else{
|
||||
pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
|
||||
}
|
||||
pTriggerStep->pIdList = pColumn;
|
||||
pTriggerStep->pUpsert = pUpsert;
|
||||
pTriggerStep->orconf = orconf;
|
||||
@@ -464,7 +470,7 @@ TriggerStep *sqlite3TriggerInsertStep(
|
||||
** sees an UPDATE statement inside the body of a CREATE TRIGGER.
|
||||
*/
|
||||
TriggerStep *sqlite3TriggerUpdateStep(
|
||||
sqlite3 *db, /* The database connection */
|
||||
Parse *pParse, /* Parser */
|
||||
Token *pTableName, /* Name of the table to be updated */
|
||||
ExprList *pEList, /* The SET clause: list of column and new values */
|
||||
Expr *pWhere, /* The WHERE clause */
|
||||
@@ -472,12 +478,20 @@ TriggerStep *sqlite3TriggerUpdateStep(
|
||||
const char *zStart, /* Start of SQL text */
|
||||
const char *zEnd /* End of SQL text */
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
TriggerStep *pTriggerStep;
|
||||
|
||||
pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName, zStart, zEnd);
|
||||
if( pTriggerStep ){
|
||||
pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
|
||||
pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
|
||||
if( IN_RENAME_COLUMN ){
|
||||
pTriggerStep->pExprList = pEList;
|
||||
pTriggerStep->pWhere = pWhere;
|
||||
pEList = 0;
|
||||
pWhere = 0;
|
||||
}else{
|
||||
pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
|
||||
pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
|
||||
}
|
||||
pTriggerStep->orconf = orconf;
|
||||
}
|
||||
sqlite3ExprListDelete(db, pEList);
|
||||
@@ -491,17 +505,23 @@ TriggerStep *sqlite3TriggerUpdateStep(
|
||||
** sees a DELETE statement inside the body of a CREATE TRIGGER.
|
||||
*/
|
||||
TriggerStep *sqlite3TriggerDeleteStep(
|
||||
sqlite3 *db, /* Database connection */
|
||||
Parse *pParse, /* Parser */
|
||||
Token *pTableName, /* The table from which rows are deleted */
|
||||
Expr *pWhere, /* The WHERE clause */
|
||||
const char *zStart, /* Start of SQL text */
|
||||
const char *zEnd /* End of SQL text */
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
TriggerStep *pTriggerStep;
|
||||
|
||||
pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName, zStart, zEnd);
|
||||
if( pTriggerStep ){
|
||||
pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
|
||||
if( IN_RENAME_COLUMN ){
|
||||
pTriggerStep->pWhere = pWhere;
|
||||
pWhere = 0;
|
||||
}else{
|
||||
pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
|
||||
}
|
||||
pTriggerStep->orconf = OE_Default;
|
||||
}
|
||||
sqlite3ExprDelete(db, pWhere);
|
||||
|
||||
Reference in New Issue
Block a user