// File: /workspace/github_c_makefile_star2_O0/barabo[P]advanced-shell-history/src/sqlite3.c
// Function: sqlite3BeginTrigger
SQLITE_PRIVATE 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 */
  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;  /* The new trigger */
  Table *pTab;            /* Table that the trigger fires off of */
  char *zName = 0;        /* Name of the trigger */
  sqlite3 *db = pParse->db;  /* The database connection */
  int iDb;                /* The database to store the trigger in */
  Token *pName;           /* The unqualified db name */
  DbFixer sFix;           /* State vector for the DB fixer */
  int iTabDb;             /* Index of the database holding pTab */

  assert( pName1!=0 );   /* pName1->z might be NULL, but not pName1 itself */
  assert( pName2!=0 );
  assert( op==TK_INSERT || op==TK_UPDATE || op==TK_DELETE );
  assert( op>0 && op<0xff );
  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 trigger will be created in */
    iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
    if( iDb<0 ){
      goto trigger_cleanup;
    }
  }
  if( !pTableName || db->mallocFailed ){
    goto trigger_cleanup;
  }

  /* A long-standing parser bug is that this syntax was allowed:
  **
  **    CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab ....
  **                                                 ^^^^^^^^
  **
  ** To maintain backwards compatibility, ignore the database
  ** name on pTableName if we are reparsing our of SQLITE_MASTER.
  */
  if( db->init.busy && iDb!=1 ){
    sqlite3DbFree(db, pTableName->a[0].zDatabase);
    pTableName->a[0].zDatabase = 0;
  }

  /* 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.
  */
  pTab = sqlite3SrcListLookup(pParse, pTableName);
  if( db->init.busy==0 && 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( db->mallocFailed ) 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. */
    if( db->init.iDb==1 ){
      /* Ticket #3810.
      ** Normally, whenever a table is dropped, all associated triggers are
      ** dropped too.  But if a TEMP trigger is created on a non-TEMP table
      ** and the table is dropped by a different database connection, the
      ** trigger is not visible to the database connection that does the
      ** drop so the trigger cannot be dropped.  This results in an
      ** "orphaned trigger" - a trigger whose associated table is missing.
      */
      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 );
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movl 0x28(%rbp), %eax
movl 0x20(%rbp), %eax
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
movq %r9, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
cmpl $0x0, 0x20(%rbp)
je 0x5c283
movq -0x18(%rbp), %rax
cmpl $0x0, 0x8(%rax)
jbe 0x5c272
movq -0x8(%rbp), %rdi
leaq 0x54de1(%rip), %rsi     # 0xb1047
movb $0x0, %al
callq 0x136f0
jmp 0x5c73f
movl $0x1, -0x4c(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x5c2a8
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
leaq -0x58(%rbp), %rcx
callq 0x5e9c0
movl %eax, -0x4c(%rbp)
cmpl $0x0, -0x4c(%rbp)
jge 0x5c2a6
jmp 0x5c73f
jmp 0x5c2a8
cmpq $0x0, 0x10(%rbp)
je 0x5c2bc
movq -0x48(%rbp), %rax
movzbl 0x50(%rax), %eax
cmpl $0x0, %eax
je 0x5c2c1
jmp 0x5c73f
movq -0x48(%rbp), %rax
movzbl 0x99(%rax), %eax
cmpl $0x0, %eax
je 0x5c2f4
cmpl $0x1, -0x4c(%rbp)
je 0x5c2f4
movq -0x48(%rbp), %rdi
movq 0x10(%rbp), %rax
movq 0x10(%rax), %rsi
callq 0x9cd0
movq 0x10(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x8(%rbp), %rdi
movq 0x10(%rbp), %rsi
callq 0x66c90
movq %rax, -0x38(%rbp)
movq -0x48(%rbp), %rax
movzbl 0x99(%rax), %eax
cmpl $0x0, %eax
jne 0x5c343
movq -0x18(%rbp), %rax
cmpl $0x0, 0x8(%rax)
jne 0x5c343
cmpq $0x0, -0x38(%rbp)
je 0x5c343
movq -0x38(%rbp), %rax
movq 0x68(%rax), %rax
movq -0x48(%rbp), %rcx
movq 0x20(%rcx), %rcx
cmpq 0x38(%rcx), %rax
jne 0x5c343
movl $0x1, -0x4c(%rbp)
movq -0x48(%rbp), %rax
cmpb $0x0, 0x50(%rax)
je 0x5c352
jmp 0x5c73f
movq -0x8(%rbp), %rsi
movl -0x4c(%rbp), %edx
movq -0x58(%rbp), %r8
leaq -0x80(%rbp), %rdi
leaq 0x5576e(%rip), %rcx     # 0xb1ad6
callq 0x66d20
cmpl $0x0, %eax
je 0x5c389
movq 0x10(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0x66dd0
cmpl $0x0, %eax
je 0x5c389
jmp 0x5c73f
movq -0x8(%rbp), %rdi
movq 0x10(%rbp), %rsi
callq 0x66c90
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0x5c3c1
movq -0x48(%rbp), %rax
movzbl 0x98(%rax), %eax
cmpl $0x1, %eax
jne 0x5c3bc
movq -0x48(%rbp), %rax
movb $0x1, 0x9a(%rax)
jmp 0x5c73f
movq -0x38(%rbp), %rax
movzbl 0x46(%rax), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x5c3e8
movq -0x8(%rbp), %rdi
leaq 0x54c99(%rip), %rsi     # 0xb1075
movb $0x0, %al
callq 0x136f0
jmp 0x5c73f
movq -0x48(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x5e840
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x5c415
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x5eab0
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
je 0x5c41a
jmp 0x5c73f
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movslq -0x4c(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x18(%rax), %rax
addq $0x38, %rax
movq %rax, -0xa8(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0x40(%rbp), %rdi
callq 0x92f0
movq -0xa8(%rbp), %rdi
movq -0xa0(%rbp), %rsi
movl %eax, %edx
callq 0x468b0
cmpq $0x0, %rax
je 0x5c49a
cmpl $0x0, 0x28(%rbp)
jne 0x5c489
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rdx
leaq 0x54c1e(%rip), %rsi     # 0xb109e
movb $0x0, %al
callq 0x136f0
jmp 0x5c495
movq -0x8(%rbp), %rdi
movl -0x4c(%rbp), %esi
callq 0x5eb40
jmp 0x5c73f
movq -0x38(%rbp), %rax
movq (%rax), %rdi
leaq 0x53440(%rip), %rsi     # 0xaf8e8
movl $0x7, %edx
callq 0x9210
cmpl $0x0, %eax
jne 0x5c4db
movq -0x8(%rbp), %rdi
leaq 0x54bf6(%rip), %rsi     # 0xb10b8
movb $0x0, %al
callq 0x136f0
movq -0x8(%rbp), %rax
movl 0x50(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x50(%rax)
jmp 0x5c73f
movq -0x38(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x5c522
cmpl $0x30, -0x1c(%rbp)
je 0x5c522
movq -0x8(%rbp), %rdi
movl -0x1c(%rbp), %ecx
leaq 0x54c10(%rip), %rdx     # 0xb110a
leaq 0x54c02(%rip), %rax     # 0xb1103
cmpl $0x22, %ecx
cmoveq %rax, %rdx
movq 0x10(%rbp), %rcx
leaq 0x54bcb(%rip), %rsi     # 0xb10de
xorl %r8d, %r8d
movb $0x0, %al
callq 0x136f0
jmp 0x5c73f
movq -0x38(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jne 0x5c550
cmpl $0x30, -0x1c(%rbp)
jne 0x5c550
movq -0x8(%rbp), %rdi
movq 0x10(%rbp), %rdx
leaq 0x54bce(%rip), %rsi     # 0xb1110
xorl %ecx, %ecx
movb $0x0, %al
callq 0x136f0
jmp 0x5c73f
movq -0x48(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x68(%rax), %rsi
callq 0x13940
movl %eax, -0x84(%rbp)
movl $0x7, -0x88(%rbp)
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movslq -0x84(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq (%rax), %rax
movq %rax, -0x90(%rbp)
cmpl $0x0, 0x20(%rbp)
je 0x5c5ac
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rax
movq %rax, -0xb0(%rbp)
jmp 0x5c5ba
movq -0x90(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, -0x98(%rbp)
cmpl $0x1, -0x84(%rbp)
je 0x5c5d7
cmpl $0x0, 0x20(%rbp)
je 0x5c5e1
movl $0x5, -0x88(%rbp)
movq -0x8(%rbp), %rdi
movl -0x88(%rbp), %esi
movq -0x40(%rbp), %rdx
movq -0x38(%rbp), %rax
movq (%rax), %rcx
movq -0x98(%rbp), %r8
callq 0x5e720
cmpl $0x0, %eax
je 0x5c60c
jmp 0x5c73f
movq -0x8(%rbp), %rdi
movl -0x84(%rbp), %ecx
leaq 0x5240b(%rip), %rdx     # 0xaea28
leaq 0x523f1(%rip), %rax     # 0xaea15
cmpl $0x1, %ecx
cmoveq %rax, %rdx
movq -0x90(%rbp), %r8
movl $0x12, %esi
xorl %eax, %eax
movl %eax, %ecx
callq 0x5e720
cmpl $0x0, %eax
je 0x5c64a
jmp 0x5c73f
cmpl $0x30, -0x1c(%rbp)
jne 0x5c657
movl $0x22, -0x1c(%rbp)
movq -0x48(%rbp), %rdi
movl $0x48, %esi
callq 0x11ca0
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x5c675
jmp 0x5c73f
movq -0x40(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq $0x0, -0x40(%rbp)
movq -0x48(%rbp), %rdi
movq 0x10(%rbp), %rax
movq 0x18(%rax), %rsi
callq 0x11720
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movslq -0x4c(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x18(%rax), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x38(%rbp), %rax
movq 0x68(%rax), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x30(%rax)
movl -0x20(%rbp), %eax
movb %al, %cl
movq -0x30(%rbp), %rax
movb %cl, 0x10(%rax)
movl -0x1c(%rbp), %edx
movl $0x2, %eax
movl $0x1, %ecx
cmpl $0x22, %edx
cmovel %ecx, %eax
movb %al, %cl
movq -0x30(%rbp), %rax
movb %cl, 0x11(%rax)
movq -0x48(%rbp), %rdi
movq 0x18(%rbp), %rsi
movl $0x1, %edx
callq 0x61690
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x48(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x622c0
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x30(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x240(%rax)
movq -0x48(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x9cd0
movq -0x48(%rbp), %rdi
movq 0x10(%rbp), %rsi
callq 0x475c0
movq -0x48(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x476c0
movq -0x48(%rbp), %rdi
movq 0x18(%rbp), %rsi
callq 0x47330
movq -0x8(%rbp), %rax
cmpq $0x0, 0x240(%rax)
jne 0x5c790
movq -0x48(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x99b0
jmp 0x5c792
jmp 0x5c792
addq $0xb0, %rsp
popq %rbp
retq
nopl (%rax,%rax)