这篇教程C++ sqlite3ExprDup函数代码示例写得很实用,希望能帮到您。
本文整理汇总了C++中sqlite3ExprDup函数的典型用法代码示例。如果您正苦于以下问题:C++ sqlite3ExprDup函数的具体用法?C++ sqlite3ExprDup怎么用?C++ sqlite3ExprDup使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。 在下文中一共展示了sqlite3ExprDup函数的21个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。 示例1: sqlite3MaterializeView/*** Evaluate a view and store its result in an ephemeral table. The** pWhere argument is an optional WHERE clause that restricts the** set of rows in the view that are to be added to the ephemeral table.*/void sqlite3MaterializeView( Parse *pParse, /* Parsing context */ Select *pView, /* View definition */ Expr *pWhere, /* Optional WHERE clause to be added */ int iCur /* Cursor number for ephemerial table */){ SelectDest dest; Select *pDup; sqlite3 *db = pParse->db; pDup = sqlite3SelectDup(db, pView); if( pWhere ){ SrcList *pFrom; pWhere = sqlite3ExprDup(db, pWhere); pFrom = sqlite3SrcListAppendFromTerm(pParse, 0, 0, 0, 0, pDup, 0, 0); pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0); } sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); sqlite3Select(pParse, pDup, &dest, 0, 0, 0); sqlite3SelectDelete(db, pDup);}
开发者ID:cdaffara,项目名称:symbiandump-os2,代码行数:27,
示例2: triggerStepAllocate/*** Construct a trigger step that implements a DELETE statement and return** a pointer to that trigger step. The parser calls this routine when it** sees a DELETE statement inside the body of a CREATE TRIGGER.*/TriggerStep *sqlite3TriggerDeleteStep( 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(pParse, TK_DELETE, pTableName,zStart,zEnd); if( pTriggerStep ){ if( IN_RENAME_OBJECT ){ pTriggerStep->pWhere = pWhere; pWhere = 0; }else{ pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); } pTriggerStep->orconf = OE_Default; } sqlite3ExprDelete(db, pWhere); return pTriggerStep;}
开发者ID:cris-auts,项目名称:linux_c_study,代码行数:28,
示例3: whereCombineDisjuncts/*** Subterms pOne and pTwo are contained within WHERE clause pWC. The** two subterms are in disjunction - they are OR-ed together.**** If these two terms are both of the form: "A op B" with the same** A and B values but different operators and if the operators are** compatible (if one is = and the other is <, for example) then** add a new virtual AND term to pWC that is the combination of the** two.**** Some examples:**** x<y OR x=y --> x<=y** x=y OR x=y --> x=y** x<=y OR x<y --> x<=y**** The following is NOT generated:**** x<y OR x>y --> x!=y */static void whereCombineDisjuncts( SrcList *pSrc, /* the FROM clause */ WhereClause *pWC, /* The complete WHERE clause */ WhereTerm *pOne, /* First disjunct */ WhereTerm *pTwo /* Second disjunct */){ u16 eOp = pOne->eOperator | pTwo->eOperator; sqlite3 *db; /* Database connection (for malloc) */ Expr *pNew; /* New virtual expression */ int op; /* Operator for the combined expression */ int idxNew; /* Index in pWC of the next virtual term */ if( (pOne->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; if( (pTwo->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; if( (eOp & (WO_EQ|WO_LT|WO_LE))!=eOp && (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return; assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 ); assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 ); if( sqlite3ExprCompare(pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return; if( sqlite3ExprCompare(pOne->pExpr->pRight, pTwo->pExpr->pRight, -1) )return; /* If we reach this point, it means the two subterms can be combined */ if( (eOp & (eOp-1))!=0 ){ if( eOp & (WO_LT|WO_LE) ){ eOp = WO_LE; }else{ assert( eOp & (WO_GT|WO_GE) ); eOp = WO_GE; } } db = pWC->pWInfo->pParse->db; pNew = sqlite3ExprDup(db, pOne->pExpr, 0); if( pNew==0 ) return; for(op=TK_EQ; eOp!=(WO_EQ<<(op-TK_EQ)); op++){ assert( op<TK_GE ); } pNew->op = op; idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); exprAnalyze(pSrc, pWC, idxNew);}
开发者ID:yaoweidong,项目名称:sqlite,代码行数:57,
示例4: sqlite3CodeRowTrigger/*** This is called to code FOR EACH ROW triggers.**** When the code that this function generates is executed, the following ** must be true:**** 1. No cursors may be open in the main database. (But newIdx and oldIdx** can be indices of cursors in temporary tables. See below.)**** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then** a temporary vdbe cursor (index newIdx) must be open and pointing at** a row containing values to be substituted for new.* expressions in the** trigger program(s).**** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then** a temporary vdbe cursor (index oldIdx) must be open and pointing at** a row containing values to be substituted for old.* expressions in the** trigger program(s).***/int sqlite3CodeRowTrigger( Parse *pParse, /* Parse context */ int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */ ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ Table *pTab, /* The table to code triggers from */ int newIdx, /* The indice of the "new" row to access */ int oldIdx, /* The indice of the "old" row to access */ int orconf, /* ON CONFLICT policy */ int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */){ Trigger *p; TriggerStack trigStackEntry; assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE); assert(tr_tm == TRIGGER_BEFORE || tr_tm == TRIGGER_AFTER ); assert(newIdx != -1 || oldIdx != -1); for(p=pTab->pTrigger; p; p=p->pNext){ int fire_this = 0; sqlite3 *db = pParse->db; /* Determine whether we should code this trigger */ if( p->op==op && p->tr_tm==tr_tm && (p->pSchema==p->pTabSchema || p->pSchema==db->aDb[1].pSchema) && (op!=TK_UPDATE||!p->pColumns||checkColumnOverLap(p->pColumns,pChanges)) ){ TriggerStack *pS; /* Pointer to trigger-stack entry */ for(pS=pParse->trigStack; pS && p!=pS->pTrigger; pS=pS->pNext){} if( !pS ){ fire_this = 1; }#if 0 /* Give no warning for recursive triggers. Just do not do them */ else{ sqlite3ErrorMsg(pParse, "recursive triggers not supported (%s)", p->name); return SQLITE_ERROR; }#endif } if( fire_this ){ int endTrigger; Expr * whenExpr; AuthContext sContext; NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; /* Push an entry on to the trigger stack */ trigStackEntry.pTrigger = p; trigStackEntry.newIdx = newIdx; trigStackEntry.oldIdx = oldIdx; trigStackEntry.pTab = pTab; trigStackEntry.pNext = pParse->trigStack; trigStackEntry.ignoreJump = ignoreJump; pParse->trigStack = &trigStackEntry; sqlite3AuthContextPush(pParse, &sContext, p->name); /* code the WHEN clause */ endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe); whenExpr = sqlite3ExprDup(db, p->pWhen); if( db->mallocFailed || sqlite3ExprResolveNames(&sNC, whenExpr) ){ pParse->trigStack = trigStackEntry.pNext; sqlite3ExprDelete(whenExpr); return 1; } sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1); sqlite3ExprDelete(whenExpr); codeTriggerProgram(pParse, p->step_list, orconf); /* Pop the entry off the trigger stack */ pParse->trigStack = trigStackEntry.pNext; sqlite3AuthContextPop(&sContext);//.........这里部分代码省略.........
开发者ID:DoktahWorm,项目名称:rhodes,代码行数:101,
示例5: codeTriggerProgram/*** 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;}
开发者ID:DoktahWorm,项目名称:rhodes,代码行数:71,
示例6: resolveCompoundOrderBy/*** Analyze the ORDER BY clause in a compound SELECT statement. Modify** each term of the ORDER BY clause is a constant integer between 1** and N where N is the number of columns in the compound SELECT.**** ORDER BY terms that are already an integer between 1 and N are** unmodified. ORDER BY terms that are integers outside the range of** 1 through N generate an error. ORDER BY terms that are expressions** are matched against result set expressions of compound SELECT** beginning with the left-most SELECT and working toward the right.** At the first match, the ORDER BY expression is transformed into** the integer column number.**** Return the number of errors seen.*/static int resolveCompoundOrderBy( Parse *pParse, /* Parsing context. Leave error messages here */ Select *pSelect /* The SELECT statement containing the ORDER BY */){ int i; ExprList *pOrderBy; ExprList *pEList; sqlite3 *db; int moreToDo = 1; pOrderBy = pSelect->pOrderBy; if( pOrderBy==0 ) return 0; db = pParse->db;#if SQLITE_MAX_COLUMN if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause"); return 1; }#endif for(i=0; i<pOrderBy->nExpr; i++){ pOrderBy->a[i].done = 0; } pSelect->pNext = 0; while( pSelect->pPrior ){ pSelect->pPrior->pNext = pSelect; pSelect = pSelect->pPrior; } while( pSelect && moreToDo ){ struct ExprList_item *pItem; moreToDo = 0; pEList = pSelect->pEList; assert( pEList!=0 ); for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ int iCol = -1; Expr *pE, *pDup; if( pItem->done ) continue; pE = pItem->pExpr; if( sqlite3ExprIsInteger(pE, &iCol) ){ if( iCol<=0 || iCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr); return 1; } }else{ iCol = resolveAsName(pParse, pEList, pE); if( iCol==0 ){ pDup = sqlite3ExprDup(db, pE, 0); if( !db->mallocFailed ){ assert(pDup); iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup); } sqlite3ExprDelete(db, pDup); } } if( iCol>0 ){ CollSeq *pColl = pE->pColl; int flags = pE->flags & EP_ExpCollate; sqlite3ExprDelete(db, pE); pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0); if( pE==0 ) return 1; pE->pColl = pColl; pE->flags |= EP_IntValue | flags; pE->u.iValue = iCol; pItem->iCol = (u16)iCol; pItem->done = 1; }else{ moreToDo = 1; } } pSelect = pSelect->pNext; } for(i=0; i<pOrderBy->nExpr; i++){ if( pOrderBy->a[i].done==0 ){ sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any " "column in the result set", i+1); return 1; } } return 0;}
开发者ID:Wushaowei001,项目名称:omnibus,代码行数:94,
示例7: updateVirtualTablestatic void updateVirtualTable( Parse *pParse, SrcList *pSrc, Table *pTab, ExprList *pChanges, Expr *pRowid, int *aXRef, Expr *pWhere ){ Vdbe *v = pParse->pVdbe; ExprList *pEList = 0; Select *pSelect = 0; Expr *pExpr; int ephemTab; int i; int addr; int iReg; sqlite3 *db = pParse->db; const char *pVTab = (const char*)sqlite3GetVTable(db, pTab); SelectDest dest; pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, "_rowid_")); if( pRowid ){ pEList = sqlite3ExprListAppend(pParse, pEList, sqlite3ExprDup(db, pRowid, 0)); } assert( pTab->iPKey<0 ); for(i=0; i<pTab->nCol; i++){ if( aXRef[i]>=0 ){ pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0); }else{ pExpr = sqlite3Expr(db, TK_ID, pTab->aCol[i].zName); } pEList = sqlite3ExprListAppend(pParse, pEList, pExpr); } pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0); assert( v ); ephemTab = pParse->nTab++; sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0)); sqlite3VdbeChangeP5(v, BTREE_UNORDERED); sqlite3SelectDestInit(&dest, SRT_Table, ephemTab); sqlite3Select(pParse, pSelect, &dest); iReg = ++pParse->nMem; pParse->nMem += pTab->nCol+1; addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0); sqlite3VdbeAddOp3(v, OP_Column, ephemTab, 0, iReg); sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1); for(i=0; i<pTab->nCol; i++){ sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i+1+(pRowid!=0), iReg+2+i); } sqlite3VtabMakeWritable(pParse, pTab); sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB); sqlite3MayAbort(pParse); sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0); sqlite3SelectDelete(db, pSelect); }
开发者ID:qtekfun,项目名称:htcDesire820Kernel,代码行数:64,
示例8: updateVirtualTable/*** Generate code for an UPDATE of a virtual table.**** The strategy is that we create an ephemerial table that contains** for each row to be changed:**** (A) The original rowid of that row.** (B) The revised rowid for the row. (note1)** (C) The content of every column in the row.**** Then we loop over this ephemeral table and for each row in** the ephermeral table call VUpdate.**** When finished, drop the ephemeral table.**** (note1) Actually, if we know in advance that (A) is always the same** as (B) we only store (A), then duplicate (A) when pulling** it out of the ephemeral table before calling VUpdate.*/static void updateVirtualTable( Parse *pParse, /* The parsing context */ SrcList *pSrc, /* The virtual table to be modified */ Table *pTab, /* The virtual table */ ExprList *pChanges, /* The columns to change in the UPDATE statement */ Expr *pRowid, /* Expression used to recompute the rowid */ int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ Expr *pWhere /* WHERE clause of the UPDATE statement */){ Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */ ExprList *pEList = 0; /* The result set of the SELECT statement */ Select *pSelect = 0; /* The SELECT statement */ Expr *pExpr; /* Temporary expression */ int ephemTab; /* Table holding the result of the SELECT */ int i; /* Loop counter */ int addr; /* Address of top of loop */ /* Construct the SELECT statement that will find the new values for ** all updated rows. */ pEList = sqlite3ExprListAppend(0, sqlite3CreateIdExpr("_rowid_"), 0); if( pRowid ){ pEList = sqlite3ExprListAppend(pEList, sqlite3ExprDup(pRowid), 0); } assert( pTab->iPKey<0 ); for(i=0; i<pTab->nCol; i++){ if( aXRef[i]>=0 ){ pExpr = sqlite3ExprDup(pChanges->a[aXRef[i]].pExpr); }else{ pExpr = sqlite3CreateIdExpr(pTab->aCol[i].zName); } pEList = sqlite3ExprListAppend(pEList, pExpr, 0); } pSelect = sqlite3SelectNew(pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0); /* Create the ephemeral table into which the update results will ** be stored. */ assert( v ); ephemTab = pParse->nTab++; sqlite3VdbeAddOp(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0)); /* fill the ephemeral table */ sqlite3Select(pParse, pSelect, SRT_Table, ephemTab, 0, 0, 0, 0); /* ** Generate code to scan the ephemeral table and call VDelete and ** VInsert */ sqlite3VdbeAddOp(v, OP_Rewind, ephemTab, 0); addr = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp(v, OP_Column, ephemTab, 0); if( pRowid ){ sqlite3VdbeAddOp(v, OP_Column, ephemTab, 1); }else{ sqlite3VdbeAddOp(v, OP_Dup, 0, 0); } for(i=0; i<pTab->nCol; i++){ sqlite3VdbeAddOp(v, OP_Column, ephemTab, i+1+(pRowid!=0)); } pParse->pVirtualLock = pTab; sqlite3VdbeOp3(v, OP_VUpdate, 0, pTab->nCol+2, (const char*)pTab->pVtab, P3_VTAB); sqlite3VdbeAddOp(v, OP_Next, ephemTab, addr); sqlite3VdbeAddOp(v, OP_Close, ephemTab, 0); /* Cleanup */ sqlite3SelectDelete(pSelect); }
开发者ID:GameLemur,项目名称:nebula-device3,代码行数:89,
示例9: codeTriggerProgram/*** 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;}
开发者ID:open2cerp,项目名称:Open2C-ERP,代码行数:68,
示例10: sqlite3ParseToplevel/* ** Create and populate a new TriggerPrg object with a sub-program ** implementing trigger pTrigger with ON CONFLICT policy orconf. */static TriggerPrg *codeRowTrigger( Parse *pParse, /* Current parse context */ Trigger *pTrigger, /* Trigger to code */ Table *pTab, /* The table pTrigger is attached to */ int orconf /* ON CONFLICT policy to code trigger program with */){ Parse *pTop = sqlite3ParseToplevel(pParse); sqlite3 *db = pParse->db; /* Database handle */ TriggerPrg *pPrg; /* Value to return */ Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */ Vdbe *v; /* Temporary VM */ NameContext sNC; /* Name context for sub-vdbe */ SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */ Parse *pSubParse; /* Parse context for sub-vdbe */ int iEndTrigger = 0; /* Label to jump to if WHEN is false */ assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); assert( pTop->pVdbe ); /* Allocate the TriggerPrg and SubProgram objects. To ensure that they ** are freed if an error occurs, link them into the Parse.pTriggerPrg ** list of the top-level Parse object sooner rather than later. */ pPrg = sqlite3DbMallocZero(db, sizeof(TriggerPrg)); if( !pPrg ) return 0; pPrg->pNext = pTop->pTriggerPrg; pTop->pTriggerPrg = pPrg; pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram)); if( !pProgram ) return 0; sqlite3VdbeLinkSubProgram(pTop->pVdbe, pProgram); pPrg->pTrigger = pTrigger; pPrg->orconf = orconf; pPrg->aColmask[0] = 0xffffffff; pPrg->aColmask[1] = 0xffffffff; /* Allocate and populate a new Parse context to use for coding the ** trigger sub-program. */ pSubParse = sqlite3StackAllocZero(db, sizeof(Parse)); if( !pSubParse ) return 0; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pSubParse; pSubParse->db = db; pSubParse->pTriggerTab = pTab; pSubParse->pToplevel = pTop; pSubParse->zAuthContext = pTrigger->zName; pSubParse->eTriggerOp = pTrigger->op; pSubParse->nQueryLoop = pParse->nQueryLoop; v = sqlite3GetVdbe(pSubParse); if( v ){ VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", pTrigger->zName, onErrorText(orconf), (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"), (pTrigger->op==TK_UPDATE ? "UPDATE" : ""), (pTrigger->op==TK_INSERT ? "INSERT" : ""), (pTrigger->op==TK_DELETE ? "DELETE" : ""), pTab->zName ));#ifndef SQLITE_OMIT_TRACE sqlite3VdbeChangeP4(v, -1, sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC );#endif /* If one was specified, code the WHEN clause. If it evaluates to false ** (or NULL) the sub-vdbe is immediately halted by jumping to the ** OP_Halt inserted at the end of the program. */ if( pTrigger->pWhen ){ pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0); if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) && db->mallocFailed==0 ){ iEndTrigger = sqlite3VdbeMakeLabel(v); sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); } sqlite3ExprDelete(db, pWhen); } /* Code the trigger program into the sub-vdbe. */ codeTriggerProgram(pSubParse, pTrigger->step_list, orconf); /* Insert an OP_Halt at the end of the sub-program. */ if( iEndTrigger ){ sqlite3VdbeResolveLabel(v, iEndTrigger); } sqlite3VdbeAddOp0(v, OP_Halt); VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf))); transferParseError(pParse, pSubParse); if( db->mallocFailed==0 ){ pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); } pProgram->nMem = pSubParse->nMem; pProgram->nCsr = pSubParse->nTab; pProgram->nOnce = pSubParse->nOnce; pProgram->token = (void *)pTrigger; pPrg->aColmask[0] = pSubParse->oldmask;//.........这里部分代码省略.........
开发者ID:pchernev,项目名称:Objective-C-iOS-Categories,代码行数:101,
示例11: First//.........这里部分代码省略......... sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol) , 0); pWhere = sqlite3ExprAnd(db, pWhere, pEq); /* For ON UPDATE, construct the next term of the WHEN clause. ** The final WHEN clause will be like this: ** ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN) */ if( pChanges ){ pEq = sqlite3PExpr(pParse, TK_IS, sqlite3PExpr(pParse, TK_DOT, sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld), sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol), 0), sqlite3PExpr(pParse, TK_DOT, sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew), sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol), 0), 0); pWhen = sqlite3ExprAnd(db, pWhen, pEq); } if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){ Expr *pNew; if( action==OE_Cascade ){ pNew = sqlite3PExpr(pParse, TK_DOT, sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew), sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol) , 0); }else if( action==OE_SetDflt ){ Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt; if( pDflt ){ pNew = sqlite3ExprDup(db, pDflt, 0); }else{ pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); } }else{ pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); } pList = sqlite3ExprListAppend(pParse, pList, pNew); sqlite3ExprListSetName(pParse, pList, &tFromCol, 0); } } sqlite3DbFree(db, aiCol); zFrom = pFKey->pFrom->zName; nFrom = sqlite3Strlen30(zFrom); if( action==OE_Restrict ){ Token tFrom; Expr *pRaise; tFrom.z = zFrom; tFrom.n = nFrom; pRaise = sqlite3Expr(db, TK_RAISE, "foreign key constraint failed"); if( pRaise ){ pRaise->affinity = OE_Abort; } pSelect = sqlite3SelectNew(pParse, sqlite3ExprListAppend(pParse, 0, pRaise), sqlite3SrcListAppend(db, 0, &tFrom, 0), pWhere, 0, 0, 0, 0, 0, 0 ); pWhere = 0;
开发者ID:77songsong,项目名称:sqlite3,代码行数:67,
示例12: exprAnalyze/*** The input to this routine is an WhereTerm structure with only the** "pExpr" field filled in. The job of this routine is to analyze the** subexpression and populate all the other fields of the WhereTerm** structure.**** If the expression is of the form "<expr> <op> X" it gets commuted** to the standard form of "X <op> <expr>".**** If the expression is of the form "X <op> Y" where both X and Y are** columns, then the original expression is unchanged and a new virtual** term of the form "Y <op> X" is added to the WHERE clause and** analyzed separately. The original term is marked with TERM_COPIED** and the new term is marked with TERM_DYNAMIC (because it's pExpr** needs to be freed with the WhereClause) and TERM_VIRTUAL (because it** is a commuted copy of a prior term.) The original term has nChild=1** and the copy has idxParent set to the index of the original term.*/static void exprAnalyze( SrcList *pSrc, /* the FROM clause */ WhereClause *pWC, /* the WHERE clause */ int idxTerm /* Index of the term to be analyzed */){ WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */ WhereTerm *pTerm; /* The term to be analyzed */ WhereMaskSet *pMaskSet; /* Set of table index masks */ Expr *pExpr; /* The expression to be analyzed */ Bitmask prereqLeft; /* Prerequesites of the pExpr->pLeft */ Bitmask prereqAll; /* Prerequesites of pExpr */ Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */ Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */ int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */ int noCase = 0; /* uppercase equivalent to lowercase */ int op; /* Top-level operator. pExpr->op */ Parse *pParse = pWInfo->pParse; /* Parsing context */ sqlite3 *db = pParse->db; /* Database connection */ if( db->mallocFailed ){ return; } pTerm = &pWC->a[idxTerm]; pMaskSet = &pWInfo->sMaskSet; pExpr = pTerm->pExpr; assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft); op = pExpr->op; if( op==TK_IN ){ assert( pExpr->pRight==0 ); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect); }else{ pTerm->prereqRight = sqlite3WhereExprListUsage(pMaskSet, pExpr->x.pList); } }else if( op==TK_ISNULL ){ pTerm->prereqRight = 0; }else{ pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight); } prereqAll = sqlite3WhereExprUsage(pMaskSet, pExpr); if( ExprHasProperty(pExpr, EP_FromJoin) ){ Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable); prereqAll |= x; extraRight = x-1; /* ON clause terms may not be used with an index ** on left table of a LEFT JOIN. Ticket #3015 */ } pTerm->prereqAll = prereqAll; pTerm->leftCursor = -1; pTerm->iParent = -1; pTerm->eOperator = 0; if( allowedOp(op) ){ Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft); Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; if( pLeft->op==TK_COLUMN ){ pTerm->leftCursor = pLeft->iTable; pTerm->u.leftColumn = pLeft->iColumn; pTerm->eOperator = operatorMask(op) & opMask; } if( op==TK_IS ) pTerm->wtFlags |= TERM_IS; if( pRight && pRight->op==TK_COLUMN ){ WhereTerm *pNew; Expr *pDup; u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */ if( pTerm->leftCursor>=0 ){ int idxNew; pDup = sqlite3ExprDup(db, pExpr, 0); if( db->mallocFailed ){ sqlite3ExprDelete(db, pDup); return; } idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); if( idxNew==0 ) return; pNew = &pWC->a[idxNew]; markTermAsChild(pWC, idxNew, idxTerm); if( op==TK_IS ) pNew->wtFlags |= TERM_IS; pTerm = &pWC->a[idxTerm]; pTerm->wtFlags |= TERM_COPIED; if( termIsEquivalence(pParse, pDup) ){ pTerm->eOperator |= WO_EQUIV;//.........这里部分代码省略.........
开发者ID:yaoweidong,项目名称:sqlite,代码行数:101,
示例13: exprAnalyzeOrTerm//.........这里部分代码省略......... pOrTerm = pOrWc->a; for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){ assert( pOrTerm->eOperator & WO_EQ ); pOrTerm->wtFlags &= ~TERM_OR_OK; if( pOrTerm->leftCursor==iCursor ){ /* This is the 2-bit case and we are on the second iteration and ** current term is from the first iteration. So skip this term. */ assert( j==1 ); continue; } if( (chngToIN & sqlite3WhereGetMask(&pWInfo->sMaskSet, pOrTerm->leftCursor))==0 ){ /* This term must be of the form t1.a==t2.b where t2 is in the ** chngToIN set but t1 is not. This term will be either preceded ** or follwed by an inverted copy (t2.b==t1.a). Skip this term ** and use its inversion. */ testcase( pOrTerm->wtFlags & TERM_COPIED ); testcase( pOrTerm->wtFlags & TERM_VIRTUAL ); assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) ); continue; } iColumn = pOrTerm->u.leftColumn; iCursor = pOrTerm->leftCursor; break; } if( i<0 ){ /* No candidate table+column was found. This can only occur ** on the second iteration */ assert( j==1 ); assert( IsPowerOfTwo(chngToIN) ); assert( chngToIN==sqlite3WhereGetMask(&pWInfo->sMaskSet, iCursor) ); break; } testcase( j==1 ); /* We have found a candidate table and column. Check to see if that ** table and column is common to every term in the OR clause */ okToChngToIN = 1; for(; i>=0 && okToChngToIN; i--, pOrTerm++){ assert( pOrTerm->eOperator & WO_EQ ); if( pOrTerm->leftCursor!=iCursor ){ pOrTerm->wtFlags &= ~TERM_OR_OK; }else if( pOrTerm->u.leftColumn!=iColumn ){ okToChngToIN = 0; }else{ int affLeft, affRight; /* If the right-hand side is also a column, then the affinities ** of both right and left sides must be such that no type ** conversions are required on the right. (Ticket #2249) */ affRight = sqlite3ExprAffinity(pOrTerm->pExpr->pRight); affLeft = sqlite3ExprAffinity(pOrTerm->pExpr->pLeft); if( affRight!=0 && affRight!=affLeft ){ okToChngToIN = 0; }else{ pOrTerm->wtFlags |= TERM_OR_OK; } } } } /* At this point, okToChngToIN is true if original pTerm satisfies ** case 1. In that case, construct a new virtual term that is ** pTerm converted into an IN operator. */ if( okToChngToIN ){ Expr *pDup; /* A transient duplicate expression */ ExprList *pList = 0; /* The RHS of the IN operator */ Expr *pLeft = 0; /* The LHS of the IN operator */ Expr *pNew; /* The complete IN operator */ for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){ if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue; assert( pOrTerm->eOperator & WO_EQ ); assert( pOrTerm->leftCursor==iCursor ); assert( pOrTerm->u.leftColumn==iColumn ); pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0); pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup); pLeft = pOrTerm->pExpr->pLeft; } assert( pLeft!=0 ); pDup = sqlite3ExprDup(db, pLeft, 0); pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0, 0); if( pNew ){ int idxNew; transferJoinMarkings(pNew, pExpr); assert( !ExprHasProperty(pNew, EP_xIsSelect) ); pNew->x.pList = pList; idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); exprAnalyze(pSrc, pWC, idxNew); pTerm = &pWC->a[idxTerm]; markTermAsChild(pWC, idxNew, idxTerm); }else{ sqlite3ExprListDelete(db, pList); } pTerm->eOperator = WO_NOOP; /* case 1 trumps case 3 */ } }}
开发者ID:yaoweidong,项目名称:sqlite,代码行数:101,
示例14: sqlite3CodeRowTrigger//.........这里部分代码省略......... ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ Table *pTab, /* The table to code triggers from */ int newIdx, /* The indice of the "new" row to access */ int oldIdx, /* The indice of the "old" row to access */ int orconf, /* ON CONFLICT policy */ int ignoreJump, /* Instruction to jump to for RAISE(IGNORE) */ u32 *piOldColMask, /* OUT: Mask of columns used from the OLD.* table */ u32 *piNewColMask /* OUT: Mask of columns used from the NEW.* table */){ Trigger *p; sqlite3 *db = pParse->db; TriggerStack trigStackEntry; trigStackEntry.oldColMask = 0; trigStackEntry.newColMask = 0; assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE); assert(tr_tm == TRIGGER_BEFORE || tr_tm == TRIGGER_AFTER ); assert(newIdx != -1 || oldIdx != -1); for(p=pTrigger; p; p=p->pNext){ int fire_this = 0; /* Sanity checking: The schema for the trigger and for the table are ** always defined. The trigger must be in the same schema as the table ** or else it must be a TEMP trigger. */ assert( p->pSchema!=0 ); assert( p->pTabSchema!=0 ); assert( p->pSchema==p->pTabSchema || p->pSchema==db->aDb[1].pSchema ); /* Determine whether we should code this trigger */ if( p->op==op && p->tr_tm==tr_tm && checkColumnOverlap(p->pColumns,pChanges) ){ TriggerStack *pS; /* Pointer to trigger-stack entry */ for(pS=pParse->trigStack; pS && p!=pS->pTrigger; pS=pS->pNext){} if( !pS ){ fire_this = 1; }#if 0 /* Give no warning for recursive triggers. Just do not do them */ else{ sqlite3ErrorMsg(pParse, "recursive triggers not supported (%s)", p->name); return SQLITE_ERROR; }#endif } if( fire_this ){ int endTrigger; Expr * whenExpr; AuthContext sContext; NameContext sNC;#ifndef SQLITE_OMIT_TRACE sqlite3VdbeAddOp4(pParse->pVdbe, OP_Trace, 0, 0, 0, sqlite3MPrintf(db, "-- TRIGGER %s", p->name), P4_DYNAMIC);#endif memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; /* Push an entry on to the trigger stack */ trigStackEntry.pTrigger = p; trigStackEntry.newIdx = newIdx; trigStackEntry.oldIdx = oldIdx; trigStackEntry.pTab = pTab; trigStackEntry.pNext = pParse->trigStack; trigStackEntry.ignoreJump = ignoreJump; pParse->trigStack = &trigStackEntry; sqlite3AuthContextPush(pParse, &sContext, p->name); /* code the WHEN clause */ endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe); whenExpr = sqlite3ExprDup(db, p->pWhen, 0); if( db->mallocFailed || sqlite3ResolveExprNames(&sNC, whenExpr) ){ pParse->trigStack = trigStackEntry.pNext; sqlite3ExprDelete(db, whenExpr); return 1; } sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, SQLITE_JUMPIFNULL); sqlite3ExprDelete(db, whenExpr); codeTriggerProgram(pParse, p->step_list, orconf); /* Pop the entry off the trigger stack */ pParse->trigStack = trigStackEntry.pNext; sqlite3AuthContextPop(&sContext); sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger); } } if( piOldColMask ) *piOldColMask |= trigStackEntry.oldColMask; if( piNewColMask ) *piNewColMask |= trigStackEntry.newColMask; return 0;}
开发者ID:Ramananda,项目名称:sqlcipher,代码行数:101,
示例15: codeTriggerProgram/* ** 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;}
开发者ID:pchernev,项目名称:Objective-C-iOS-Categories,代码行数:84,
示例16: sqlite3BeginTrigger//.........这里部分代码省略......... */ db->init.orphanTrigger = 1; } goto trigger_cleanup; } if( IsVirtual(pTab) ){ sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); goto trigger_cleanup; } /* Check that the trigger name is not reserved and that no trigger of the ** specified name exists */ zName = sqlite3NameFromToken(db, pName); if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto trigger_cleanup; } assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName, sqlite3Strlen30(zName)) ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); }else{ assert( !db->init.busy ); sqlite3CodeVerifySchema(pParse, iDb); } goto trigger_cleanup; } /* Do not create a trigger on a system table */ if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ sqlite3ErrorMsg(pParse, "cannot create trigger on system table"); pParse->nErr++; goto trigger_cleanup; } /* INSTEAD of triggers are only for views and views only support INSTEAD ** of triggers. */ if( pTab->pSelect && tr_tm!=TK_INSTEAD ){ sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0); goto trigger_cleanup; } if( !pTab->pSelect && tr_tm==TK_INSTEAD ){ sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF" " trigger on table: %S", pTableName, 0); goto trigger_cleanup; } iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); #ifndef SQLITE_OMIT_AUTHORIZATION { int code = SQLITE_CREATE_TRIGGER; const char *zDb = db->aDb[iTabDb].zName; const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb; if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER; if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){ goto trigger_cleanup; } if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){ goto trigger_cleanup; } }#endif /* INSTEAD OF triggers can only appear on views and BEFORE triggers ** cannot appear on views. So we might as well translate every ** INSTEAD OF trigger into a BEFORE trigger. It simplifies code ** elsewhere. */ if (tr_tm == TK_INSTEAD){ tr_tm = TK_BEFORE; } /* Build the Trigger object */ pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger)); if( pTrigger==0 ) goto trigger_cleanup; pTrigger->zName = zName; zName = 0; pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName); pTrigger->pSchema = db->aDb[iDb].pSchema; pTrigger->pTabSchema = pTab->pSchema; pTrigger->op = (u8)op; pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); pTrigger->pColumns = sqlite3IdListDup(db, pColumns); assert( pParse->pNewTrigger==0 ); pParse->pNewTrigger = pTrigger; trigger_cleanup: sqlite3DbFree(db, zName); sqlite3SrcListDelete(db, pTableName); sqlite3IdListDelete(db, pColumns); sqlite3ExprDelete(db, pWhen); if( !pParse->pNewTrigger ){ sqlite3DeleteTrigger(db, pTrigger); }else{ assert( pParse->pNewTrigger==pTrigger ); }}
开发者ID:pchernev,项目名称:Objective-C-iOS-Categories,代码行数:101,
示例17: codeTriggerProgram/*** 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;}
开发者ID:AchironOS,项目名称:chromium-2,代码行数:75,
示例18: sqlite3BeginTrigger//.........这里部分代码省略......... pTab = sqlite3SrcListLookup(pParse, pTableName); if( pName2->n==0 && pTab && pTab->iDb==1 ){ iDb = 1; } /* Ensure the table name matches database name and that the table exists */ if( sqlite3_malloc_failed ) goto trigger_cleanup; assert( pTableName->nSrc==1 ); if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && sqlite3FixSrcList(&sFix, pTableName) ){ goto trigger_cleanup; } pTab = sqlite3SrcListLookup(pParse, pTableName); if( !pTab ){ /* The table does not exist. */ goto trigger_cleanup; } /* Check that the trigger name is not reserved and that no trigger of the ** specified name exists */ zName = sqlite3NameFromToken(pName); if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto trigger_cleanup; } if( sqlite3HashFind(&(db->aDb[iDb].trigHash), zName,pName->n+1) ){ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); goto trigger_cleanup; } /* Do not create a trigger on a system table */ if( (iDb!=1 && sqlite3StrICmp(pTab->zName, MASTER_NAME)==0) || (iDb==1 && sqlite3StrICmp(pTab->zName, TEMP_MASTER_NAME)==0) ){ sqlite3ErrorMsg(pParse, "cannot create trigger on system table"); pParse->nErr++; goto trigger_cleanup; } /* INSTEAD of triggers are only for views and views only support INSTEAD ** of triggers. */ if( pTab->pSelect && tr_tm!=TK_INSTEAD ){ sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0); goto trigger_cleanup; } if( !pTab->pSelect && tr_tm==TK_INSTEAD ){ sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF" " trigger on table: %S", pTableName, 0); goto trigger_cleanup; }#ifndef SQLITE_OMIT_AUTHORIZATION { int code = SQLITE_CREATE_TRIGGER; const char *zDb = db->aDb[pTab->iDb].zName; const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb; if( pTab->iDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER; if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){ goto trigger_cleanup; } if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(pTab->iDb), 0, zDb)){ goto trigger_cleanup; } }#endif /* INSTEAD OF triggers can only appear on views and BEFORE triggers ** cannot appear on views. So we might as well translate every ** INSTEAD OF trigger into a BEFORE trigger. It simplifies code ** elsewhere. */ if (tr_tm == TK_INSTEAD){ tr_tm = TK_BEFORE; } /* Build the Trigger object */ pTrigger = (Trigger*)sqliteMalloc(sizeof(Trigger)); if( pTrigger==0 ) goto trigger_cleanup; pTrigger->name = zName; zName = 0; pTrigger->table = sqliteStrDup(pTableName->a[0].zName); if( sqlite3_malloc_failed ) goto trigger_cleanup; pTrigger->iDb = iDb; pTrigger->iTabDb = pTab->iDb; pTrigger->op = op; pTrigger->tr_tm = tr_tm; pTrigger->pWhen = sqlite3ExprDup(pWhen); pTrigger->pColumns = sqlite3IdListDup(pColumns); pTrigger->foreach = foreach; sqlite3TokenCopy(&pTrigger->nameToken,pName); assert( pParse->pNewTrigger==0 ); pParse->pNewTrigger = pTrigger;trigger_cleanup: sqliteFree(zName); sqlite3SrcListDelete(pTableName); sqlite3IdListDelete(pColumns); sqlite3ExprDelete(pWhen);}
开发者ID:open2cerp,项目名称:Open2C-ERP,代码行数:101,
示例19: updateVirtualTable/*** Generate code for an UPDATE of a virtual table.**** The strategy is that we create an ephemerial table that contains** for each row to be changed:**** (A) The original rowid of that row.** (B) The revised rowid for the row. (note1)** (C) The content of every column in the row.**** Then we loop over this ephemeral table and for each row in** the ephermeral table call VUpdate.**** When finished, drop the ephemeral table.**** (note1) Actually, if we know in advance that (A) is always the same** as (B) we only store (A), then duplicate (A) when pulling** it out of the ephemeral table before calling VUpdate.*/static void updateVirtualTable( Parse *pParse, /* The parsing context */ SrcList *pSrc, /* The virtual table to be modified */ Table *pTab, /* The virtual table */ ExprList *pChanges, /* The columns to change in the UPDATE statement */ Expr *pRowid, /* Expression used to recompute the rowid */ int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ Expr *pWhere /* WHERE clause of the UPDATE statement */){ Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */ ExprList *pEList = 0; /* The result set of the SELECT statement */ Select *pSelect = 0; /* The SELECT statement */ Expr *pExpr; /* Temporary expression */ int ephemTab; /* Table holding the result of the SELECT */ int i; /* Loop counter */ int addr; /* Address of top of loop */ int iReg; /* First register in set passed to OP_VUpdate */ sqlite3 *db = pParse->db; /* Database connection */ const char *pVTab = (const char*)sqlite3GetVTable(db, pTab); SelectDest dest; /* Construct the SELECT statement that will find the new values for ** all updated rows. */ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, "_rowid_")); if( pRowid ){ pEList = sqlite3ExprListAppend(pParse, pEList, sqlite3ExprDup(db, pRowid, 0)); } assert( pTab->iPKey<0 ); for(i=0; i<pTab->nCol; i++){ if( aXRef[i]>=0 ){ pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0); }else{ pExpr = sqlite3Expr(db, TK_ID, pTab->aCol[i].zName); } pEList = sqlite3ExprListAppend(pParse, pEList, pExpr); } pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0); /* Create the ephemeral table into which the update results will ** be stored. */ assert( v ); ephemTab = pParse->nTab++; sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0)); sqlite3VdbeChangeP5(v, BTREE_UNORDERED); /* fill the ephemeral table */ sqlite3SelectDestInit(&dest, SRT_Table, ephemTab); sqlite3Select(pParse, pSelect, &dest); /* Generate code to scan the ephemeral table and call VUpdate. */ iReg = ++pParse->nMem; pParse->nMem += pTab->nCol+1; addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0); sqlite3VdbeAddOp3(v, OP_Column, ephemTab, 0, iReg); sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1); for(i=0; i<pTab->nCol; i++){ sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i+1+(pRowid!=0), iReg+2+i); } sqlite3VtabMakeWritable(pParse, pTab); sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB); sqlite3MayAbort(pParse); sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0); /* Cleanup */ sqlite3SelectDelete(db, pSelect); }
开发者ID:Sheridan,项目名称:sqlite,代码行数:91,
示例20: sqlite3CodeRowTrigger/*** This is called to code FOR EACH ROW triggers.**** When the code that this function generates is executed, the following ** must be true:**** 1. No cursors may be open in the main database. (But newIdx and oldIdx** can be indices of cursors in temporary tables. See below.)**** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then** a temporary vdbe cursor (index newIdx) must be open and pointing at** a row containing values to be substituted for new.* expressions in the** trigger program(s).**** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then** a temporary vdbe cursor (index oldIdx) must be open and pointing at** a row containing values to be substituted for old.* expressions in the** trigger program(s).***/int sqlite3CodeRowTrigger( Parse *pParse, /* Parse context */ int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */ ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ int tr_tm, /* One of TK_BEFORE, TK_AFTER */ Table *pTab, /* The table to code triggers from */ int newIdx, /* The indice of the "new" row to access */ int oldIdx, /* The indice of the "old" row to access */ int orconf, /* ON CONFLICT policy */ int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */){ Trigger * pTrigger; TriggerStack * pTriggerStack; assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE); assert(tr_tm == TK_BEFORE || tr_tm == TK_AFTER ); assert(newIdx != -1 || oldIdx != -1); pTrigger = pTab->pTrigger; while( pTrigger ){ int fire_this = 0; /* determine whether we should code this trigger */ if( pTrigger->op == op && pTrigger->tr_tm == tr_tm && pTrigger->foreach == TK_ROW ){ fire_this = 1; pTriggerStack = pParse->trigStack; while( pTriggerStack ){ if( pTriggerStack->pTrigger == pTrigger ){ fire_this = 0; } pTriggerStack = pTriggerStack->pNext; } if( op == TK_UPDATE && pTrigger->pColumns && !checkColumnOverLap(pTrigger->pColumns, pChanges) ){ fire_this = 0; } } if( fire_this && (pTriggerStack = sqliteMalloc(sizeof(TriggerStack)))!=0 ){ int endTrigger; SrcList dummyTablist; Expr * whenExpr; AuthContext sContext; dummyTablist.nSrc = 0; /* Push an entry on to the trigger stack */ pTriggerStack->pTrigger = pTrigger; pTriggerStack->newIdx = newIdx; pTriggerStack->oldIdx = oldIdx; pTriggerStack->pTab = pTab; pTriggerStack->pNext = pParse->trigStack; pTriggerStack->ignoreJump = ignoreJump; pParse->trigStack = pTriggerStack; sqlite3AuthContextPush(pParse, &sContext, pTrigger->name); /* code the WHEN clause */ endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe); whenExpr = sqlite3ExprDup(pTrigger->pWhen); if( sqlite3ExprResolveIds(pParse, &dummyTablist, 0, whenExpr) ){ pParse->trigStack = pParse->trigStack->pNext; sqliteFree(pTriggerStack); sqlite3ExprDelete(whenExpr); return 1; } sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1); sqlite3ExprDelete(whenExpr); sqlite3VdbeAddOp(pParse->pVdbe, OP_ContextPush, 0, 0); codeTriggerProgram(pParse, pTrigger->step_list, orconf); sqlite3VdbeAddOp(pParse->pVdbe, OP_ContextPop, 0, 0); /* Pop the entry off the trigger stack */ pParse->trigStack = pParse->trigStack->pNext; sqlite3AuthContextPop(&sContext); sqliteFree(pTriggerStack); sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger);//.........这里部分代码省略.........
开发者ID:open2cerp,项目名称:Open2C-ERP,代码行数:101,
示例21: sqlite3CodeRowTrigger/*** This is called to code FOR EACH ROW triggers.**** When the code that this function generates is executed, the following ** must be true:**** 1. No cursors may be open in the main database. (But newIdx and oldIdx** can be indices of cursors in temporary tables. See below.)**** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then** a temporary vdbe cursor (index newIdx) must be open and pointing at** a row containing values to be substituted for new.* expressions in the** trigger program(s).**** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then** a temporary vdbe cursor (index oldIdx) must be open and pointing at** a row containing values to be substituted for old.* expressions in the** trigger program(s).***/int sqlite3CodeRowTrigger( Parse *pParse, /* Parse context */ int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */ ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ Table *pTab, /* The table to code triggers from */ int newIdx, /* The indice of the "new" row to access */ int oldIdx, /* The indice of the "old" row to access */ int orconf, /* ON CONFLICT policy */ int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */){ Trigger *pTrigger; TriggerStack *pStack; TriggerStack trigStackEntry; assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE); assert(tr_tm == TRIGGER_BEFORE || tr_tm == TRIGGER_AFTER ); assert(newIdx != -1 || oldIdx != -1); pTrigger = pTab->pTrigger; while( pTrigger ){ int fire_this = 0; /* determine whether we should code this trigger */ if( pTrigger->op == op && pTrigger->tr_tm == tr_tm ){ fire_this = 1; for(pStack=pParse->trigStack; pStack; pStack=pStack->pNext){ if( pStack->pTrigger==pTrigger ){ fire_this = 0; } } if( op == TK_UPDATE && pTrigger->pColumns && !checkColumnOverLap(pTrigger->pColumns, pChanges) ){ fire_this = 0; } } if( fire_this ){ int endTrigger; Expr * whenExpr; AuthContext sContext; NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; /* Push an entry on to the trigger stack */ trigStackEntry.pTrigger = pTrigger; trigStackEntry.newIdx = newIdx; trigStackEntry.oldIdx = oldIdx; trigStackEntry.pTab = pTab; trigStackEntry.pNext = pParse->trigStack; trigStackEntry.ignoreJump = ignoreJump; pParse->trigStack = &trigStackEntry; sqlite3AuthContextPush(pParse, &sContext, pTrigger->name); /* code the WHEN clause */ endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe); whenExpr = sqlite3ExprDup(pTrigger->pWhen); if( sqlite3ExprResolveNames(&sNC, whenExpr) ){ pParse->trigStack = trigStackEntry.pNext; sqlite3ExprDelete(whenExpr); return 1; } sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1); sqlite3ExprDelete(whenExpr); codeTriggerProgram(pParse, pTrigger->step_list, orconf); /* Pop the entry off the trigger stack */ pParse->trigStack = trigStackEntry.pNext; sqlite3AuthContextPop(&sContext); sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger); } pTrigger = pTrigger->pNext; } return 0;}
开发者ID:huangyt,项目名称:foundations.github.com,代码行数:100,
注:本文中的sqlite3ExprDup函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 C++ sqlite3FindTable函数代码示例 C++ sqlite3ExprDelete函数代码示例 |