예제 #1
0
/*
** Generate VDBE code for zero or more statements inside the body of a
** trigger.  
*/
static int codeTriggerProgram(
  Parse *pParse,            /* The parser context */
  TriggerStep *pStepList,   /* List of statements inside the trigger body */
  int orconfin              /* Conflict algorithm. (OE_Abort, etc) */  
){
  TriggerStep * pTriggerStep = pStepList;
  int orconf;

  while( pTriggerStep ){
    int saveNTab = pParse->nTab;
 
    orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
    pParse->trigStack->orconf = orconf;
    switch( pTriggerStep->op ){
      case TK_SELECT: {
	Select * ss = sqlite3SelectDup(pTriggerStep->pSelect);		  
	assert(ss);
	assert(ss->pSrc);
	sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0, 0);
	sqlite3SelectDelete(ss);
	break;
      }
      case TK_UPDATE: {
        SrcList *pSrc;
        pSrc = targetSrcList(pParse, pTriggerStep);
        sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 0, 0);
        sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
        sqlite3Update(pParse, pSrc,
		sqlite3ExprListDup(pTriggerStep->pExprList), 
		sqlite3ExprDup(pTriggerStep->pWhere), orconf);
        sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
        sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 1, 0);
        break;
      }
      case TK_INSERT: {
        SrcList *pSrc;
        pSrc = targetSrcList(pParse, pTriggerStep);
        sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 0, 0);
        sqlite3Insert(pParse, pSrc,
          sqlite3ExprListDup(pTriggerStep->pExprList), 
          sqlite3SelectDup(pTriggerStep->pSelect), 
          sqlite3IdListDup(pTriggerStep->pIdList), orconf);
        sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 1, 0);
        break;
      }
      case TK_DELETE: {
        SrcList *pSrc;
        sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 0, 0);
        sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
        pSrc = targetSrcList(pParse, pTriggerStep);
        sqlite3DeleteFrom(pParse, pSrc, sqlite3ExprDup(pTriggerStep->pWhere));
        sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
        sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 1, 0);
        break;
      }
      default:
        assert(0);
    } 
    pParse->nTab = saveNTab;
    pTriggerStep = pTriggerStep->pNext;
  }

  return 0;
}
예제 #2
0
/*
** Generate VDBE code for zero or more statements inside the body of a
** trigger.  
*/
static int codeTriggerProgram(
  Parse *pParse,            /* The parser context */
  TriggerStep *pStepList,   /* List of statements inside the trigger body */
  int orconfin              /* Conflict algorithm. (OE_Abort, etc) */  
){
  TriggerStep * pTriggerStep = pStepList;
  int orconf;
  Vdbe *v = pParse->pVdbe;
  sqlite3 *db = pParse->db;

  assert( pTriggerStep!=0 );
  assert( v!=0 );
  sqlite3VdbeAddOp(v, OP_ContextPush, 0, 0);
  VdbeComment((v, "# begin trigger %s", pStepList->pTrig->name));
  while( pTriggerStep ){
    orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
    pParse->trigStack->orconf = orconf;
    switch( pTriggerStep->op ){
      case TK_SELECT: {
        Select *ss = sqlite3SelectDup(db, pTriggerStep->pSelect);
        if( ss ){
          sqlite3SelectResolve(pParse, ss, 0);
          sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0, 0);
          sqlite3SelectDelete(ss);
        }
        break;
      }
      case TK_UPDATE: {
        SrcList *pSrc;
        pSrc = targetSrcList(pParse, pTriggerStep);
        sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
        sqlite3Update(pParse, pSrc,
                sqlite3ExprListDup(db, pTriggerStep->pExprList), 
                sqlite3ExprDup(db, pTriggerStep->pWhere), orconf);
        sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
        break;
      }
      case TK_INSERT: {
        SrcList *pSrc;
        pSrc = targetSrcList(pParse, pTriggerStep);
        sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
        sqlite3Insert(pParse, pSrc,
          sqlite3ExprListDup(db, pTriggerStep->pExprList), 
          sqlite3SelectDup(db, pTriggerStep->pSelect), 
          sqlite3IdListDup(db, pTriggerStep->pIdList), orconf);
        sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
        break;
      }
      case TK_DELETE: {
        SrcList *pSrc;
        sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
        pSrc = targetSrcList(pParse, pTriggerStep);
        sqlite3DeleteFrom(pParse, pSrc, 
                          sqlite3ExprDup(db, pTriggerStep->pWhere));
        sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
        break;
      }
      default:
        assert(0);
    } 
    pTriggerStep = pTriggerStep->pNext;
  }
  sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
  VdbeComment((v, "# end trigger %s", pStepList->pTrig->name));

  return 0;
}
예제 #3
0
/*
 ** Generate VDBE code for the statements inside the body of a single
 ** trigger.
 */
static int codeTriggerProgram(
                              Parse *pParse,            /* The parser context */
                              TriggerStep *pStepList,   /* List of statements inside the trigger body */
                              int orconf                /* Conflict algorithm. (OE_Abort, etc) */
){
    TriggerStep *pStep;
    Vdbe *v = pParse->pVdbe;
    sqlite3 *db = pParse->db;
    
    assert( pParse->pTriggerTab && pParse->pToplevel );
    assert( pStepList );
    assert( v!=0 );
    for(pStep=pStepList; pStep; pStep=pStep->pNext){
        /* Figure out the ON CONFLICT policy that will be used for this step
         ** of the trigger program. If the statement that caused this trigger
         ** to fire had an explicit ON CONFLICT, then use it. Otherwise, use
         ** the ON CONFLICT policy that was specified as part of the trigger
         ** step statement. Example:
         **
         **   CREATE TRIGGER AFTER INSERT ON t1 BEGIN;
         **     INSERT OR REPLACE INTO t2 VALUES(new.a, new.b);
         **   END;
         **
         **   INSERT INTO t1 ... ;            -- insert into t2 uses REPLACE policy
         **   INSERT OR IGNORE INTO t1 ... ;  -- insert into t2 uses IGNORE policy
         */
        pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
        
        /* Clear the cookieGoto flag. When coding triggers, the cookieGoto
         ** variable is used as a flag to indicate to sqlite3ExprCodeConstants()
         ** that it is not safe to refactor constants (this happens after the
         ** start of the first loop in the SQL statement is coded - at that
         ** point code may be conditionally executed, so it is no longer safe to
         ** initialize constant register values).  */
        assert( pParse->cookieGoto==0 || pParse->cookieGoto==-1 );
        pParse->cookieGoto = 0;
        
        switch( pStep->op ){
            case TK_UPDATE: {
                sqlite3Update(pParse,
                              targetSrcList(pParse, pStep),
                              sqlite3ExprListDup(db, pStep->pExprList, 0),
                              sqlite3ExprDup(db, pStep->pWhere, 0),
                              pParse->eOrconf
                              );
                break;
            }
            case TK_INSERT: {
                sqlite3Insert(pParse,
                              targetSrcList(pParse, pStep),
                              sqlite3ExprListDup(db, pStep->pExprList, 0),
                              sqlite3SelectDup(db, pStep->pSelect, 0),
                              sqlite3IdListDup(db, pStep->pIdList),
                              pParse->eOrconf
                              );
                break;
            }
            case TK_DELETE: {
                sqlite3DeleteFrom(pParse,
                                  targetSrcList(pParse, pStep),
                                  sqlite3ExprDup(db, pStep->pWhere, 0)
                                  );
                break;
            }
            default: assert( pStep->op==TK_SELECT ); {
                SelectDest sDest;
                Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0);
                sqlite3SelectDestInit(&sDest, SRT_Discard, 0);
                sqlite3Select(pParse, pSelect, &sDest);
                sqlite3SelectDelete(db, pSelect);
                break;
            }
        }
        if( pStep->op!=TK_SELECT ){
            sqlite3VdbeAddOp0(v, OP_ResetCount);
        }
    }
    
    return 0;
}
예제 #4
0
/*
** Generate VDBE code for the statements inside the body of a single 
** trigger.
*/
static int codeTriggerProgram(
  Parse *pParse,            /* The parser context */
  TriggerStep *pStepList,   /* List of statements inside the trigger body */
  int orconf                /* Conflict algorithm. (OE_Abort, etc) */  
){
  TriggerStep *pStep;
  Vdbe *v = pParse->pVdbe;
  sqlite3 *db = pParse->db;

  assert( pParse->pTriggerTab && pParse->pToplevel );
  assert( pStepList );
  assert( v!=0 );
  for(pStep=pStepList; pStep; pStep=pStep->pNext){
    /* Figure out the ON CONFLICT policy that will be used for this step
    ** of the trigger program. If the statement that caused this trigger
    ** to fire had an explicit ON CONFLICT, then use it. Otherwise, use
    ** the ON CONFLICT policy that was specified as part of the trigger
    ** step statement. Example:
    **
    **   CREATE TRIGGER AFTER INSERT ON t1 BEGIN;
    **     INSERT OR REPLACE INTO t2 VALUES(new.a, new.b);
    **   END;
    **
    **   INSERT INTO t1 ... ;            -- insert into t2 uses REPLACE policy
    **   INSERT OR IGNORE INTO t1 ... ;  -- insert into t2 uses IGNORE policy
    */
    pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
    assert( pParse->okConstFactor==0 );

    switch( pStep->op ){
      case TK_UPDATE: {
        sqlite3Update(pParse, 
          targetSrcList(pParse, pStep),
          sqlite3ExprListDup(db, pStep->pExprList, 0), 
          sqlite3ExprDup(db, pStep->pWhere, 0), 
          pParse->eOrconf
        );
        break;
      }
      case TK_INSERT: {
        sqlite3Insert(pParse, 
          targetSrcList(pParse, pStep),
          sqlite3SelectDup(db, pStep->pSelect, 0), 
          sqlite3IdListDup(db, pStep->pIdList), 
          pParse->eOrconf
        );
        break;
      }
      case TK_DELETE: {
        sqlite3DeleteFrom(pParse, 
          targetSrcList(pParse, pStep),
          sqlite3ExprDup(db, pStep->pWhere, 0)
        );
        break;
      }
      default: assert( pStep->op==TK_SELECT ); {
        SelectDest sDest;
        Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0);
        sqlite3SelectDestInit(&sDest, SRT_Discard, 0);
        sqlite3Select(pParse, pSelect, &sDest);
        sqlite3SelectDelete(db, pSelect);
        break;
      }
    } 
    if( pStep->op!=TK_SELECT ){
      sqlite3VdbeAddOp0(v, OP_ResetCount);
    }
  }

  return 0;
}