您当前的位置:首页 > IT编程 > C++
| C语言 | Java | VB | VC | python | Android | TensorFlow | C++ | oracle | 学术与代码 | cnn卷积神经网络 | gnn | 图像修复 | Keras | 数据集 | Neo4j | 自然语言处理 | 深度学习 | 医学CAD | 医学影像 | 超参数 | pointnet | pytorch | 异常检测 | Transformers | 情感分类 | 知识图谱 |

自学教程:C++ sqlite3ExprDup函数代码示例

51自学网 2021-06-03 08:13:51
  C++
这篇教程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: updateVirtualTable

static 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函数代码示例
万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。