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; }
/* ** Convert the pStep->target token into a SrcList and return a pointer ** to that SrcList. ** ** This routine adds a specific database name, if needed, to the target when ** forming the SrcList. This prevents a trigger in one database from ** referring to a target in another database. An exception is when the ** trigger is in TEMP in which case it can refer to any other database it ** wants. */ static SrcList *targetSrcList( Parse *pParse, /* The parsing context */ TriggerStep *pStep /* The trigger containing the target token */ ){ Token sDb; /* Dummy database name token */ int iDb; /* Index of the database to use */ SrcList *pSrc; /* SrcList to be returned */ iDb = pStep->pTrig->iDb; if( iDb==0 || iDb>=2 ){ assert( iDb<pParse->db->nDb ); sDb.z = pParse->db->aDb[iDb].zName; sDb.n = strlen(sDb.z); pSrc = sqliteSrcListAppend(0, &sDb, &pStep->target); } else { pSrc = sqliteSrcListAppend(0, &pStep->target, 0); } return pSrc; }