亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? trigger.c

?? sqlite 3.3.8 支持加密的版本
?? C
?? 第 1 頁 / 共 2 頁
字號:
/*
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
*
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_TRIGGER
/*
** Delete a linked list of TriggerStep structures.
*/
void sqlite3DeleteTriggerStep(TriggerStep *pTriggerStep){
  while( pTriggerStep ){
    TriggerStep * pTmp = pTriggerStep;
    pTriggerStep = pTriggerStep->pNext;

    if( pTmp->target.dyn ) sqliteFree((char*)pTmp->target.z);
    sqlite3ExprDelete(pTmp->pWhere);
    sqlite3ExprListDelete(pTmp->pExprList);
    sqlite3SelectDelete(pTmp->pSelect);
    sqlite3IdListDelete(pTmp->pIdList);

    sqliteFree(pTmp);
  }
}

/*
** This is called by the parser when it sees a CREATE TRIGGER statement
** up to the point of the BEGIN before the trigger actions.  A Trigger
** structure is generated based on the information available and stored
** in pParse->pNewTrigger.  After the trigger actions have been parsed, the
** sqlite3FinishTrigger() function is called to complete the trigger
** construction process.
*/
void sqlite3BeginTrigger(
  Parse *pParse,      /* The parse context of the CREATE TRIGGER statement */
  Token *pName1,      /* The name of the trigger */
  Token *pName2,      /* The name of the trigger */
  int tr_tm,          /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */
  int op,             /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
  IdList *pColumns,   /* column list if this is an UPDATE OF trigger */
  SrcList *pTableName,/* The name of the table/view the trigger applies to */
  int foreach,        /* One of TK_ROW or TK_STATEMENT */
  Expr *pWhen,        /* WHEN clause */
  int isTemp,         /* True if the TEMPORARY keyword is present */
  int noErr           /* Suppress errors if the trigger already exists */
){
  Trigger *pTrigger = 0;
  Table *pTab;
  char *zName = 0;        /* Name of the trigger */
  sqlite3 *db = pParse->db;
  int iDb;                /* The database to store the trigger in */
  Token *pName;           /* The unqualified db name */
  DbFixer sFix;
  int iTabDb;

  assert( pName1!=0 );   /* pName1->z might be NULL, but not pName1 itself */
  assert( pName2!=0 );
  if( isTemp ){
    /* If TEMP was specified, then the trigger name may not be qualified. */
    if( pName2->n>0 ){
      sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name");
      goto trigger_cleanup;
    }
    iDb = 1;
    pName = pName1;
  }else{
    /* Figure out the db that the the trigger will be created in */
    iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
    if( iDb<0 ){
      goto trigger_cleanup;
    }
  }

  /* If the trigger name was unqualified, and the table is a temp table,
  ** then set iDb to 1 to create the trigger in the temporary database.
  ** If sqlite3SrcListLookup() returns 0, indicating the table does not
  ** exist, the error is caught by the block below.
  */
  if( !pTableName || sqlite3MallocFailed() ){
    goto trigger_cleanup;
  }
  pTab = sqlite3SrcListLookup(pParse, pTableName);
  if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
    iDb = 1;
  }

  /* Ensure the table name matches database name and that the table exists */
  if( sqlite3MallocFailed() ) 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;
  }
  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(pName);
  if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
    goto trigger_cleanup;
  }
  if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName,strlen(zName)) ){
    if( !noErr ){
      sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
    }
    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*)sqliteMalloc(sizeof(Trigger));
  if( pTrigger==0 ) goto trigger_cleanup;
  pTrigger->name = zName;
  zName = 0;
  pTrigger->table = sqliteStrDup(pTableName->a[0].zName);
  pTrigger->pSchema = db->aDb[iDb].pSchema;
  pTrigger->pTabSchema = pTab->pSchema;
  pTrigger->op = op;
  pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
  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);
  if( !pParse->pNewTrigger ){
    sqlite3DeleteTrigger(pTrigger);
  }else{
    assert( pParse->pNewTrigger==pTrigger );
  }
}

/*
** This routine is called after all of the trigger actions have been parsed
** in order to complete the process of building the trigger.
*/
void sqlite3FinishTrigger(
  Parse *pParse,          /* Parser context */
  TriggerStep *pStepList, /* The triggered program */
  Token *pAll             /* Token that describes the complete CREATE TRIGGER */
){
  Trigger *pTrig = 0;     /* The trigger whose construction is finishing up */
  sqlite3 *db = pParse->db;  /* The database */
  DbFixer sFix;
  int iDb;                   /* Database containing the trigger */

  pTrig = pParse->pNewTrigger;
  pParse->pNewTrigger = 0;
  if( pParse->nErr || !pTrig ) goto triggerfinish_cleanup;
  iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
  pTrig->step_list = pStepList;
  while( pStepList ){
    pStepList->pTrig = pTrig;
    pStepList = pStepList->pNext;
  }
  if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &pTrig->nameToken) 
          && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
    goto triggerfinish_cleanup;
  }

  /* if we are not initializing, and this trigger is not on a TEMP table, 
  ** build the sqlite_master entry
  */
  if( !db->init.busy ){
    static const VdbeOpList insertTrig[] = {
      { OP_NewRowid,   0, 0,  0          },
      { OP_String8,    0, 0,  "trigger"  },
      { OP_String8,    0, 0,  0          },  /* 2: trigger name */
      { OP_String8,    0, 0,  0          },  /* 3: table name */
      { OP_Integer,    0, 0,  0          },
      { OP_String8,    0, 0,  "CREATE TRIGGER "},
      { OP_String8,    0, 0,  0          },  /* 6: SQL */
      { OP_Concat,     0, 0,  0          }, 
      { OP_MakeRecord, 5, 0,  "aaada"    },
      { OP_Insert,     0, 0,  0          },
    };
    int addr;
    Vdbe *v;

    /* Make an entry in the sqlite_master table */
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) goto triggerfinish_cleanup;
    sqlite3BeginWriteOperation(pParse, 0, iDb);
    sqlite3OpenMasterTable(pParse, iDb);
    addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
    sqlite3VdbeChangeP3(v, addr+2, pTrig->name, 0); 
    sqlite3VdbeChangeP3(v, addr+3, pTrig->table, 0); 
    sqlite3VdbeChangeP3(v, addr+6, (char*)pAll->z, pAll->n);
    sqlite3ChangeCookie(db, v, iDb);
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
    sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, 
       sqlite3MPrintf("type='trigger' AND name='%q'", pTrig->name), P3_DYNAMIC);
  }

  if( db->init.busy ){
    int n;
    Table *pTab;
    Trigger *pDel;
    pDel = sqlite3HashInsert(&db->aDb[iDb].pSchema->trigHash, 
                     pTrig->name, strlen(pTrig->name), pTrig);
    if( pDel ){
      assert( sqlite3MallocFailed() && pDel==pTrig );
      goto triggerfinish_cleanup;
    }
    n = strlen(pTrig->table) + 1;
    pTab = sqlite3HashFind(&pTrig->pTabSchema->tblHash, pTrig->table, n);
    assert( pTab!=0 );
    pTrig->pNext = pTab->pTrigger;
    pTab->pTrigger = pTrig;
    pTrig = 0;
  }

triggerfinish_cleanup:
  sqlite3DeleteTrigger(pTrig);
  assert( !pParse->pNewTrigger );
  sqlite3DeleteTriggerStep(pStepList);
}

/*
** Make a copy of all components of the given trigger step.  This has
** the effect of copying all Expr.token.z values into memory obtained
** from sqliteMalloc().  As initially created, the Expr.token.z values
** all point to the input string that was fed to the parser.  But that
** string is ephemeral - it will go away as soon as the sqlite3_exec()
** call that started the parser exits.  This routine makes a persistent
** copy of all the Expr.token.z strings so that the TriggerStep structure
** will be valid even after the sqlite3_exec() call returns.
*/
static void sqlitePersistTriggerStep(TriggerStep *p){
  if( p->target.z ){
    p->target.z = (u8*)sqliteStrNDup((char*)p->target.z, p->target.n);
    p->target.dyn = 1;
  }
  if( p->pSelect ){
    Select *pNew = sqlite3SelectDup(p->pSelect);
    sqlite3SelectDelete(p->pSelect);
    p->pSelect = pNew;
  }
  if( p->pWhere ){
    Expr *pNew = sqlite3ExprDup(p->pWhere);
    sqlite3ExprDelete(p->pWhere);
    p->pWhere = pNew;
  }
  if( p->pExprList ){
    ExprList *pNew = sqlite3ExprListDup(p->pExprList);
    sqlite3ExprListDelete(p->pExprList);
    p->pExprList = pNew;
  }
  if( p->pIdList ){
    IdList *pNew = sqlite3IdListDup(p->pIdList);
    sqlite3IdListDelete(p->pIdList);
    p->pIdList = pNew;
  }
}

/*
** Turn a SELECT statement (that the pSelect parameter points to) into
** a trigger step.  Return a pointer to a TriggerStep structure.
**
** The parser calls this routine when it finds a SELECT statement in
** body of a TRIGGER.  
*/
TriggerStep *sqlite3TriggerSelectStep(Select *pSelect){
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
  if( pTriggerStep==0 ) {
    sqlite3SelectDelete(pSelect);
    return 0;
  }

  pTriggerStep->op = TK_SELECT;
  pTriggerStep->pSelect = pSelect;
  pTriggerStep->orconf = OE_Default;
  sqlitePersistTriggerStep(pTriggerStep);

  return pTriggerStep;
}

/*
** Build a trigger step out of an INSERT statement.  Return a pointer
** to the new trigger step.
**
** The parser calls this routine when it sees an INSERT inside the
** body of a trigger.
*/
TriggerStep *sqlite3TriggerInsertStep(
  Token *pTableName,  /* Name of the table into which we insert */
  IdList *pColumn,    /* List of columns in pTableName to insert into */
  ExprList *pEList,   /* The VALUE clause: a list of values to be inserted */
  Select *pSelect,    /* A SELECT statement that supplies values */
  int orconf          /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
){
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));

  assert(pEList == 0 || pSelect == 0);
  assert(pEList != 0 || pSelect != 0);

  if( pTriggerStep ){
    pTriggerStep->op = TK_INSERT;
    pTriggerStep->pSelect = pSelect;
    pTriggerStep->target  = *pTableName;
    pTriggerStep->pIdList = pColumn;
    pTriggerStep->pExprList = pEList;
    pTriggerStep->orconf = orconf;
    sqlitePersistTriggerStep(pTriggerStep);
  }else{
    sqlite3IdListDelete(pColumn);
    sqlite3ExprListDelete(pEList);
    sqlite3SelectDup(pSelect);
  }

  return pTriggerStep;
}

/*
** Construct a trigger step that implements an UPDATE statement and return
** a pointer to that trigger step.  The parser calls this routine when it
** sees an UPDATE statement inside the body of a CREATE TRIGGER.
*/
TriggerStep *sqlite3TriggerUpdateStep(
  Token *pTableName,   /* Name of the table to be updated */
  ExprList *pEList,    /* The SET clause: list of column and new values */
  Expr *pWhere,        /* The WHERE clause */
  int orconf           /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
){
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
  if( pTriggerStep==0 ) return 0;

  pTriggerStep->op = TK_UPDATE;
  pTriggerStep->target  = *pTableName;
  pTriggerStep->pExprList = pEList;
  pTriggerStep->pWhere = pWhere;
  pTriggerStep->orconf = orconf;
  sqlitePersistTriggerStep(pTriggerStep);

  return pTriggerStep;
}

/*
** 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(Token *pTableName, Expr *pWhere){
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
  if( pTriggerStep==0 ) return 0;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品国产自产拍高清av王其 | 天堂av在线一区| 91在线观看地址| 亚洲女人的天堂| 欧美片网站yy| 久久99久国产精品黄毛片色诱| 欧美电影免费观看高清完整版| 国产一区二区三区精品视频| 国产精品久久三区| 精品视频999| 免费高清视频精品| 久久久久久97三级| 99riav一区二区三区| 亚洲黄色小视频| 欧美军同video69gay| 国产一区二区调教| 亚洲人成网站色在线观看| 精品视频1区2区| 国产精品18久久久久| 亚洲国产高清aⅴ视频| 欧美色综合影院| 国产在线看一区| 亚洲色图.com| 欧美成人性战久久| av激情成人网| 天天综合色天天综合色h| 久久久综合视频| 91激情五月电影| 久草这里只有精品视频| 亚洲啪啪综合av一区二区三区| 欧美精品一二三区| 成人一区二区三区| 日本美女视频一区二区| 亚洲欧洲综合另类| 久久婷婷成人综合色| 欧美性videosxxxxx| 粉嫩久久99精品久久久久久夜 | 日韩成人精品视频| 国产精品精品国产色婷婷| 日韩一区二区三区免费看| 99re这里只有精品6| 激情综合色综合久久综合| 一区二区三区四区在线播放| 欧美电视剧免费观看| 欧美专区亚洲专区| 成人做爰69片免费看网站| 美女一区二区三区| 亚洲v精品v日韩v欧美v专区| 国产精品美女久久久久久久久 | 91麻豆.com| 国产精华液一区二区三区| 日本欧美加勒比视频| 亚洲午夜免费视频| 亚洲人成网站色在线观看| 久久精品一区八戒影视| 精品国产一区二区国模嫣然| 欧美日韩国产综合视频在线观看| 91污片在线观看| 国产精品12区| 韩国中文字幕2020精品| 日本不卡123| 无码av中文一区二区三区桃花岛| 中文字幕一区在线观看| 国产欧美一区二区精品忘忧草 | 国产精品人成在线观看免费| 精品国产亚洲一区二区三区在线观看 | 国产精品网曝门| 久久久精品蜜桃| 久久众筹精品私拍模特| 日韩欧美中文字幕公布| 88在线观看91蜜桃国自产| 91精品黄色片免费大全| 91精品免费在线观看| 欧美日韩高清一区二区不卡| 欧美三级韩国三级日本三斤| 在线观看三级视频欧美| 在线影视一区二区三区| 欧美专区日韩专区| 欧美亚洲愉拍一区二区| 欧美日韩国产欧美日美国产精品| 欧美视频在线播放| 欧美日韩中文精品| 欧美精品丝袜久久久中文字幕| 欧美日韩一级黄| 日韩一区二区中文字幕| 亚洲视频一二区| 一区二区三区四区中文字幕| 亚洲午夜久久久久中文字幕久| 亚洲国产精品天堂| 青青草原综合久久大伊人精品| 日韩和欧美的一区| 国产一区91精品张津瑜| 成人午夜精品在线| 色婷婷狠狠综合| 在线免费不卡视频| 欧美电影一区二区三区| 久久综合色综合88| 中文字幕中文字幕一区二区| 亚洲精品一二三| 三级欧美在线一区| 高清在线观看日韩| 色婷婷综合视频在线观看| 777午夜精品视频在线播放| 精品国产乱码久久久久久闺蜜| 亚洲国产精品精华液2区45| 一区二区三区在线不卡| 老司机一区二区| 99久久99精品久久久久久| 精品视频1区2区| 久久久久9999亚洲精品| 亚洲精品欧美综合四区| 另类小说图片综合网| 99久久久国产精品免费蜜臀| 欧美一区二区不卡视频| 国产精品素人一区二区| 日日夜夜免费精品视频| 成人av电影免费观看| 日韩一区二区三区精品视频 | ㊣最新国产の精品bt伙计久久| 亚洲一区中文日韩| 国产在线视频不卡二| 欧美日韩精品免费| 中文字幕国产精品一区二区| 日韩电影在线看| 99国产一区二区三精品乱码| 欧美电影免费观看完整版| 亚洲人妖av一区二区| 国内国产精品久久| 欧美日免费三级在线| 国产精品嫩草影院av蜜臀| 视频在线观看一区二区三区| 99国产精品国产精品久久| 2017欧美狠狠色| 日韩中文字幕不卡| 91麻豆精品一区二区三区| 国产欧美一区二区精品忘忧草 | 欧美日韩一区二区三区免费看| 日本一区二区三区电影| 人人精品人人爱| 色噜噜狠狠成人中文综合| 国产无一区二区| 精品一区二区在线视频| 欧美疯狂做受xxxx富婆| 亚洲女同一区二区| av不卡在线播放| 国产欧美综合在线| 国产精品一卡二| 欧美tickle裸体挠脚心vk| 五月激情六月综合| 欧美性欧美巨大黑白大战| 亚洲人精品一区| 91网站视频在线观看| 亚洲综合免费观看高清在线观看| 福利91精品一区二区三区| 日韩欧美的一区| 秋霞av亚洲一区二区三| 777午夜精品免费视频| 亚洲一卡二卡三卡四卡| av亚洲产国偷v产偷v自拍| 中文在线资源观看网站视频免费不卡 | 日日夜夜精品视频天天综合网| 在线观看www91| 一区二区三区鲁丝不卡| 欧洲精品中文字幕| 亚洲一二三四在线观看| 日本道精品一区二区三区| 一区二区三区四区五区视频在线观看| 99久久99精品久久久久久 | 欧美日韩国产综合草草| 亚洲高清中文字幕| 欧美嫩在线观看| 国产日韩影视精品| 欧美一区二区免费| **性色生活片久久毛片| 国产一区二区三区观看| 精东粉嫩av免费一区二区三区| 欧美一级日韩不卡播放免费| 亚洲欧洲av在线| 日韩精品久久理论片| 国产精品99久久久久久有的能看 | 成人高清av在线| 国产一区二区三区电影在线观看| 亚洲一区二区在线免费观看视频| 91蜜桃网址入口| 亚洲午夜一二三区视频| 制服丝袜亚洲播放| 久久99国产乱子伦精品免费| 久久影院电视剧免费观看| 国产精品一二三区在线| 亚洲视频在线一区二区| 欧美日免费三级在线| 蜜桃视频一区二区| 国产亚洲精品bt天堂精选| 岛国精品在线播放| 亚洲午夜在线观看视频在线| 51精品视频一区二区三区| 奇米综合一区二区三区精品视频| 精品国产91亚洲一区二区三区婷婷| 国产一区二区h| 亚洲综合丁香婷婷六月香|