Beispiel #1
0
void sqliteDropProc(Parse *pParse, Token *pName){
  Object *pObj;
  char *zName;
  Vdbe *v = sqliteGetVdbe(pParse);
  sqlite *db = pParse->db;

  zName = sqliteStrNDup(pName->z, pName->n);
  sqliteDequote(zName);
  pObj = sqliteHashFind(&(db->aDb[0].objectHash), zName, pName->n+1);
  if( !pParse->explain && !pObj ){
    sqliteErrorMsg(pParse, "no such object: %T", pName);
    goto dropobject_cleanup;
  }

  /* Generate code to destroy the database record of the trigger.
  */
  if( v ){
    int base;
    static VdbeOpList dropObject[] = {
      { OP_Rewind,     0, ADDR(9),  0},
      { OP_String,     0, 0,        0}, /* 1 */
      { OP_Column,     0, 1,        0},
      { OP_Ne,         0, ADDR(8),  0},
      { OP_String,     0, 0,        "procedure"},
      { OP_Column,     0, 0,        0},
      { OP_Ne,         0, ADDR(8),  0},
      { OP_Delete,     0, 0,        0},
      { OP_Next,       0, ADDR(1),  0}, /* 8 */
    };

    sqliteBeginWriteOperation(pParse, 0, 0);
    sqliteOpenMasterTable(v, 0);
    base = sqliteVdbeAddOpList(v,  ArraySize(dropObject), dropObject);
    sqliteVdbeChangeP3(v, base+1, zName, 0);
    if( pObj && pObj->iDb==0 ){
      sqliteChangeCookie(db, v);
    }
    sqliteVdbeAddOp(v, OP_Close, 0, 0);
    sqliteEndWriteOperation(pParse);
  }

  /*
   * If this is not an "explain", then delete the trigger structure.
   */
  if( !pParse->explain ){
    sqliteHashInsert(&(db->aDb[pObj->iDb].objectHash), zName, pName->n+1, 0);
    sqliteDeleteObject(pObj);
  }

dropobject_cleanup:
  sqliteFree(zName);
}
Beispiel #2
0
/*
** This routine is called after the body of the procedure has been parsed
** in order to complete the process of building the procedure object.
*/
void sqliteFinishProc(
  Parse *pParse,          /* Parser context */
  Block *pBlock,		  /* The procedure body */
  Token *pAll             /* Token that describes the complete CREATE text */
){
  Object *no = 0;           /* The object whose construction is finishing up */
  sqlite *db = pParse->db;  /* The database */
  Vdbe *v = sqliteGetVdbe(pParse);

  if( pParse->nErr || pParse->pNewObject==0 ) goto objectfinish_cleanup;
  no = pParse->pNewObject;
  pParse->pNewObject = 0;

  sqliteCompileBlock(pParse, pBlock);
  sqliteVdbeAddOp(v, OP_Halt, 0, 0);

  /* save compiled body code, reset vdbe */
  if( !pParse->explain ){
    no->nOp = v->nOp;
    v->nOp = 0;
    no->aOp = v->aOp;
    v->aOp = 0;
    v->nOpAlloc = 0;
  }
  DbClearProperty(db, 0, DB_Locked);
  DbClearProperty(db, 1, DB_Locked);

  /* if we are not initializing build the sqlite_master entry */
  if( !db->init.busy ){
    static VdbeOpList insertObj[] = {
      { OP_NewRecno,   0, 0,  0           },
      { OP_String,     0, 0,  "procedure" },
      { OP_String,     0, 0,  0           },  /* 2: object name */
      { OP_String,     0, 0,  0           },  
      { OP_Integer,    0, 0,  0           },
      { OP_String,     0, 0,  0           },  /* 5: SQL */
      { OP_MakeRecord, 5, 0,  0           },
      { OP_PutIntKey,  0, 0,  0           },
    };
    int addr;

    /* Make an entry in the sqlite_master table */
    if( v==0 ) goto objectfinish_cleanup;
    sqliteBeginWriteOperation(pParse, 0, 0);
    sqliteOpenMasterTable(v, 0);
    addr = sqliteVdbeAddOpList(v, ArraySize(insertObj), insertObj);
    sqliteVdbeChangeP3(v, addr+2, no->name, 0); 
    sqliteVdbeChangeP3(v, addr+5, pAll->z, pAll->n);
    if( no->iDb==0 ){
      sqliteChangeCookie(db, v);
    }
    sqliteVdbeAddOp(v, OP_Close, 0, 0);
    sqliteEndWriteOperation(pParse);
  }

  if( !pParse->explain ){
    sqliteHashInsert(&db->aDb[no->iDb].objectHash, 
                     no->name, strlen(no->name)+1, no);
    no = 0;
  }

objectfinish_cleanup:
  sqliteDeleteObject(no);
  sqliteDeleteObject(pParse->pNewObject);
  pParse->pNewObject = 0;
}
Beispiel #3
0
/*
** Drop a trigger given a pointer to that trigger.  If nested is false,
** then also generate code to remove the trigger from the SQLITE_MASTER
** table.
*/
void sqliteDropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
  Table   *pTable;
  Vdbe *v;
  sqlite *db = pParse->db;

  assert( pTrigger->iDb<db->nDb );
  if( pTrigger->iDb>=2 ){
    sqliteErrorMsg(pParse, "triggers may not be removed from "
       "auxiliary database %s", db->aDb[pTrigger->iDb].zName);
    return;
  }
  pTable = sqliteFindTable(db, pTrigger->table,db->aDb[pTrigger->iTabDb].zName);
  assert(pTable);
  assert( pTable->iDb==pTrigger->iDb || pTrigger->iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_TRIGGER;
    const char *zDb = db->aDb[pTrigger->iDb].zName;
    const char *zTab = SCHEMA_TABLE(pTrigger->iDb);
    if( pTrigger->iDb ) code = SQLITE_DROP_TEMP_TRIGGER;
    if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
      sqliteAuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
      return;
    }
  }
#endif

  /* Generate code to destroy the database record of the trigger.
  */
  if( pTable!=0 && !nested && (v = sqliteGetVdbe(pParse))!=0 ){
    int base;
    static VdbeOpList dropTrigger[] = {
      { OP_Rewind,     0, ADDR(9),  0},
      { OP_String,     0, 0,        0}, /* 1 */
      { OP_Column,     0, 1,        0},
      { OP_Ne,         0, ADDR(8),  0},
      { OP_String,     0, 0,        "trigger"},
      { OP_Column,     0, 0,        0},
      { OP_Ne,         0, ADDR(8),  0},
      { OP_Delete,     0, 0,        0},
      { OP_Next,       0, ADDR(1),  0}, /* 8 */
    };

    sqliteBeginWriteOperation(pParse, 0, 0);
    sqliteOpenMasterTable(v, pTrigger->iDb);
    base = sqliteVdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
    sqliteVdbeChangeP3(v, base+1, pTrigger->name, 0);
    if( pTrigger->iDb==0 ){
      sqliteChangeCookie(db, v);
    }
    sqliteVdbeAddOp(v, OP_Close, 0, 0);
    sqliteEndWriteOperation(pParse);
  }

  /*
   * If this is not an "explain", then delete the trigger structure.
   */
  if( !pParse->explain ){
    const char *zName = pTrigger->name;
    int nName = strlen(zName);
    if( pTable->pTrigger == pTrigger ){
      pTable->pTrigger = pTrigger->pNext;
    }else{
      Trigger *cc = pTable->pTrigger;
      while( cc ){ 
        if( cc->pNext == pTrigger ){
          cc->pNext = cc->pNext->pNext;
          break;
        }
        cc = cc->pNext;
      }
      assert(cc);
    }
    sqliteHashInsert(&(db->aDb[pTrigger->iDb].trigHash), zName, nName+1, 0);
    sqliteDeleteTrigger(pTrigger);
  }
}
Beispiel #4
0
/*
** This routine is called after all of the trigger actions have been parsed
** in order to complete the process of building the trigger.
*/
void sqliteFinishTrigger(
  Parse *pParse,          /* Parser context */
  TriggerStep *pStepList, /* The triggered program */
  Token *pAll             /* Token that describes the complete CREATE TRIGGER */
){
  Trigger *nt = 0;          /* The trigger whose construction is finishing up */
  sqlite *db = pParse->db;  /* The database */
  DbFixer sFix;

  if( pParse->nErr || pParse->pNewTrigger==0 ) goto triggerfinish_cleanup;
  nt = pParse->pNewTrigger;
  pParse->pNewTrigger = 0;
  nt->step_list = pStepList;
  while( pStepList ){
    pStepList->pTrig = nt;
    pStepList = pStepList->pNext;
  }
  if( sqliteFixInit(&sFix, pParse, nt->iDb, "trigger", &nt->nameToken) 
          && sqliteFixTriggerStep(&sFix, nt->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 VdbeOpList insertTrig[] = {
      { OP_NewRecno,   0, 0,  0          },
      { OP_String,     0, 0,  "trigger"  },
      { OP_String,     0, 0,  0          },  /* 2: trigger name */
      { OP_String,     0, 0,  0          },  /* 3: table name */
      { OP_Integer,    0, 0,  0          },
      { OP_String,     0, 0,  0          },  /* 5: SQL */
      { OP_MakeRecord, 5, 0,  0          },
      { OP_PutIntKey,  0, 0,  0          },
    };
    int addr;
    Vdbe *v;

    /* Make an entry in the sqlite_master table */
    v = sqliteGetVdbe(pParse);
    if( v==0 ) goto triggerfinish_cleanup;
    sqliteBeginWriteOperation(pParse, 0, 0);
    sqliteOpenMasterTable(v, nt->iDb);
    addr = sqliteVdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
    sqliteVdbeChangeP3(v, addr+2, nt->name, 0); 
    sqliteVdbeChangeP3(v, addr+3, nt->table, 0); 
    sqliteVdbeChangeP3(v, addr+5, pAll->z, pAll->n);
    if( nt->iDb==0 ){
      sqliteChangeCookie(db, v);
    }
    sqliteVdbeAddOp(v, OP_Close, 0, 0);
    sqliteEndWriteOperation(pParse);
  }

  if( !pParse->explain ){
    Table *pTab;
    sqliteHashInsert(&db->aDb[nt->iDb].trigHash, 
                     nt->name, strlen(nt->name)+1, nt);
    pTab = sqliteLocateTable(pParse, nt->table, db->aDb[nt->iTabDb].zName);
    assert( pTab!=0 );
    nt->pNext = pTab->pTrigger;
    pTab->pTrigger = nt;
    nt = 0;
  }

triggerfinish_cleanup:
  sqliteDeleteTrigger(nt);
  sqliteDeleteTrigger(pParse->pNewTrigger);
  pParse->pNewTrigger = 0;
  sqliteDeleteTriggerStep(pStepList);
}