mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Show the text of individual statements within a trigger, as they
execute, as comments in the output from sqlite3_trace() and sqlite3_trace_v2(). FossilOrigin-Name: fe3d2b97d8945e6a9636472f77bcdc92cc5dda8b3e6e3a4fcbdd0a212ea5b9aa
This commit is contained in:
@@ -25,6 +25,7 @@ void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerStep){
|
||||
sqlite3ExprListDelete(db, pTmp->pExprList);
|
||||
sqlite3SelectDelete(db, pTmp->pSelect);
|
||||
sqlite3IdListDelete(db, pTmp->pIdList);
|
||||
sqlite3DbFree(db, pTmp->zSpan);
|
||||
|
||||
sqlite3DbFree(db, pTmp);
|
||||
}
|
||||
@@ -339,6 +340,17 @@ triggerfinish_cleanup:
|
||||
sqlite3DeleteTriggerStep(db, pStepList);
|
||||
}
|
||||
|
||||
/*
|
||||
** Duplicate a range of text from an SQL statement, then convert all
|
||||
** whitespace characters into ordinary space characters.
|
||||
*/
|
||||
static char *triggerSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){
|
||||
char *z = sqlite3DbSpanDup(db, zStart, zEnd);
|
||||
int i;
|
||||
if( z ) for(i=0; z[i]; i++) if( sqlite3Isspace(z[i]) ) z[i] = ' ';
|
||||
return z;
|
||||
}
|
||||
|
||||
/*
|
||||
** Turn a SELECT statement (that the pSelect parameter points to) into
|
||||
** a trigger step. Return a pointer to a TriggerStep structure.
|
||||
@@ -346,7 +358,12 @@ triggerfinish_cleanup:
|
||||
** The parser calls this routine when it finds a SELECT statement in
|
||||
** body of a TRIGGER.
|
||||
*/
|
||||
TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){
|
||||
TriggerStep *sqlite3TriggerSelectStep(
|
||||
sqlite3 *db, /* Database connection */
|
||||
Select *pSelect, /* The SELECT statement */
|
||||
const char *zStart, /* Start of SQL text */
|
||||
const char *zEnd /* End of SQL text */
|
||||
){
|
||||
TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
|
||||
if( pTriggerStep==0 ) {
|
||||
sqlite3SelectDelete(db, pSelect);
|
||||
@@ -355,6 +372,7 @@ TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){
|
||||
pTriggerStep->op = TK_SELECT;
|
||||
pTriggerStep->pSelect = pSelect;
|
||||
pTriggerStep->orconf = OE_Default;
|
||||
pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
|
||||
return pTriggerStep;
|
||||
}
|
||||
|
||||
@@ -367,7 +385,9 @@ TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){
|
||||
static TriggerStep *triggerStepAllocate(
|
||||
sqlite3 *db, /* Database connection */
|
||||
u8 op, /* Trigger opcode */
|
||||
Token *pName /* The target name */
|
||||
Token *pName, /* The target name */
|
||||
const char *zStart, /* Start of SQL text */
|
||||
const char *zEnd /* End of SQL text */
|
||||
){
|
||||
TriggerStep *pTriggerStep;
|
||||
|
||||
@@ -378,6 +398,7 @@ static TriggerStep *triggerStepAllocate(
|
||||
sqlite3Dequote(z);
|
||||
pTriggerStep->zTarget = z;
|
||||
pTriggerStep->op = op;
|
||||
pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
|
||||
}
|
||||
return pTriggerStep;
|
||||
}
|
||||
@@ -394,13 +415,15 @@ TriggerStep *sqlite3TriggerInsertStep(
|
||||
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 */
|
||||
u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
|
||||
u8 orconf, /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
|
||||
const char *zStart, /* Start of SQL text */
|
||||
const char *zEnd /* End of SQL text */
|
||||
){
|
||||
TriggerStep *pTriggerStep;
|
||||
|
||||
assert(pSelect != 0 || db->mallocFailed);
|
||||
|
||||
pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
|
||||
pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName, zStart, zEnd);
|
||||
if( pTriggerStep ){
|
||||
pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
|
||||
pTriggerStep->pIdList = pColumn;
|
||||
@@ -423,11 +446,13 @@ TriggerStep *sqlite3TriggerUpdateStep(
|
||||
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 */
|
||||
u8 orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
|
||||
u8 orconf, /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
|
||||
const char *zStart, /* Start of SQL text */
|
||||
const char *zEnd /* End of SQL text */
|
||||
){
|
||||
TriggerStep *pTriggerStep;
|
||||
|
||||
pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName);
|
||||
pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName, zStart, zEnd);
|
||||
if( pTriggerStep ){
|
||||
pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
|
||||
pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
|
||||
@@ -446,11 +471,13 @@ TriggerStep *sqlite3TriggerUpdateStep(
|
||||
TriggerStep *sqlite3TriggerDeleteStep(
|
||||
sqlite3 *db, /* Database connection */
|
||||
Token *pTableName, /* The table from which rows are deleted */
|
||||
Expr *pWhere /* The WHERE clause */
|
||||
Expr *pWhere, /* The WHERE clause */
|
||||
const char *zStart, /* Start of SQL text */
|
||||
const char *zEnd /* End of SQL text */
|
||||
){
|
||||
TriggerStep *pTriggerStep;
|
||||
|
||||
pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName);
|
||||
pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName, zStart, zEnd);
|
||||
if( pTriggerStep ){
|
||||
pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
|
||||
pTriggerStep->orconf = OE_Default;
|
||||
@@ -705,6 +732,12 @@ static int codeTriggerProgram(
|
||||
pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
|
||||
assert( pParse->okConstFactor==0 );
|
||||
|
||||
#ifndef SQLITE_OMIT_TRACE
|
||||
sqlite3VdbeAddOp4(v, OP_Trace, 0x7fffffff, 1, 0,
|
||||
sqlite3MPrintf(db, "-- %s", pStep->zSpan),
|
||||
P4_DYNAMIC);
|
||||
#endif
|
||||
|
||||
switch( pStep->op ){
|
||||
case TK_UPDATE: {
|
||||
sqlite3Update(pParse,
|
||||
|
Reference in New Issue
Block a user