int sqliteCompileSQLStmt(Parse *pParse, Block *b, SQLStmt* pSql){ Vdbe *v = sqliteGetVdbe(pParse); int i,j; switch( pSql->op ){ case TK_SELECT: { assert(pSql->pSelect); assert(pSql->pSelect->pSrc); sqliteSelect(pParse, pSql->pSelect, SRT_Stack, 0, 0, 0, 0); if( pSql->pExprList->nExpr!=pSql->pSelect->pEList->nExpr ) { sqliteErrorMsg(pParse, "INTO list does not match column list", 0); return 1; } for(i=0; i<pSql->pExprList->nExpr; i++) { Expr *e = pSql->pExprList->a[i].pExpr; if( e->op!=TK_ID ) { sqliteErrorMsg(pParse, "Bad lvalue in INTO list", 0); return 1; } if( sqliteExprProcResolve(pParse, b, e) ){ return 1; } assert( e->op==TK_VAR ); if( e->flags==EP_NotNull ){ j = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_NotNull, -1, i); sqliteVdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort, "attempt to store null in non-null var", P3_STATIC); sqliteVdbeResolveLabel(v, j); } sqliteVdbeAddOp(v, OP_MemStore, e->iColumn, 1); } break; } case TK_UPDATE: { SrcList *pSrc; pSrc = sqliteSrcListAppend(0, &pSql->target, 0); sqliteUpdate(pParse, pSrc, pSql->pExprList, pSql->pWhere, pSql->orconf); break; } case TK_INSERT: { SrcList *pSrc; pSrc = sqliteSrcListAppend(0, &pSql->target, 0); sqliteInsert(pParse, pSrc, pSql->pExprList, pSql->pSelect, pSql->pIdList, pSql->orconf); break; } case TK_DELETE: { SrcList *pSrc; pSrc = sqliteSrcListAppend(0, &pSql->target, 0); sqliteDeleteFrom(pParse, pSrc, pSql->pWhere); break; } default: assert(0); } return 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 = sqliteSelectDup(pTriggerStep->pSelect); assert(ss); assert(ss->pSrc); sqliteSelect(pParse, ss, SRT_Discard, 0, 0, 0, 0); sqliteSelectDelete(ss); break; } case TK_UPDATE: { SrcList *pSrc; pSrc = targetSrcList(pParse, pTriggerStep); sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0); sqliteUpdate(pParse, pSrc, sqliteExprListDup(pTriggerStep->pExprList), sqliteExprDup(pTriggerStep->pWhere), orconf); sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0); break; } case TK_INSERT: { SrcList *pSrc; pSrc = targetSrcList(pParse, pTriggerStep); sqliteInsert(pParse, pSrc, sqliteExprListDup(pTriggerStep->pExprList), sqliteSelectDup(pTriggerStep->pSelect), sqliteIdListDup(pTriggerStep->pIdList), orconf); break; } case TK_DELETE: { SrcList *pSrc; sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0); pSrc = targetSrcList(pParse, pTriggerStep); sqliteDeleteFrom(pParse, pSrc, sqliteExprDup(pTriggerStep->pWhere)); sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0); break; } default: assert(0); } pParse->nTab = saveNTab; pTriggerStep = pTriggerStep->pNext; } return 0; }