// File: /workspace/github_c_makefile_star2_O1/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %r9, -0x30(%rbp)
movq %rdx, %r15
movq %rdi, %rbx
movl 0x28(%rbp), %edi
movl 0x20(%rbp), %r13d
movq 0x18(%rbp), %rax
movq %rax, -0x68(%rbp)
movq 0x10(%rbp), %rdx
movq (%rbx), %r14
testl %r13d, %r13d
movq %rdx, -0x48(%rbp)
je 0x442ff
cmpl $0x0, 0x8(%r15)
je 0x44333
leaq 0x3825e(%rip), %rsi     # 0x7c54b
xorl %r15d, %r15d
movq %rbx, %rdi
xorl %eax, %eax
callq 0x11724
jmp 0x443c4
movl %edi, -0x38(%rbp)
movl %r8d, -0x54(%rbp)
movl %ecx, -0x3c(%rbp)
leaq -0x70(%rbp), %rcx
movq %rbx, %rdi
movq %r15, %rdx
callq 0x45ec1
movq -0x48(%rbp), %rdx
movl %eax, %r12d
testl %eax, %eax
sets %al
testq %rdx, %rdx
sete %cl
orb %al, %cl
je 0x4434c
jmp 0x443c1
movl %edi, -0x38(%rbp)
movl %r8d, -0x54(%rbp)
movl %ecx, -0x3c(%rbp)
movq %rsi, -0x70(%rbp)
movl $0x1, %r12d
testq %rdx, %rdx
je 0x443c1
cmpb $0x0, 0x50(%r14)
jne 0x443c1
cmpl $0x1, %r12d
je 0x4437b
cmpb $0x0, 0x99(%r14)
je 0x4437b
movq 0x10(%rdx), %rsi
movq %r14, %rdi
callq 0x9c3a
movq -0x48(%rbp), %rdx
movq $0x0, 0x10(%rdx)
movq %rbx, %rdi
movq %rdx, %rsi
callq 0x4baec
cmpb $0x0, 0x99(%r14)
jne 0x443ba
cmpl $0x0, 0x8(%r15)
sete %cl
testq %rax, %rax
setne %dl
andb %cl, %dl
cmpb $0x1, %dl
jne 0x443ba
movq 0x68(%rax), %rax
movq 0x20(%r14), %rcx
cmpq 0x38(%rcx), %rax
movl $0x1, %eax
cmovel %eax, %r12d
cmpb $0x0, 0x50(%r14)
je 0x44431
xorl %r15d, %r15d
xorl %r12d, %r12d
movq -0x30(%rbp), %r13
movq %r14, %rdi
movq %r15, %rsi
callq 0x9c3a
movq %r14, %rdi
movq -0x48(%rbp), %rsi
callq 0x341f5
movq %r14, %rdi
movq %r13, %rsi
callq 0x3429d
movq %r14, %rdi
movq -0x68(%rbp), %rsi
callq 0x34068
cmpq $0x0, 0x240(%rbx)
je 0x44415
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r14, %rdi
movq %r12, %rsi
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x98df
movq -0x70(%rbp), %r15
testl %r12d, %r12d
sets %al
cmpl $0x1, %r12d
sete %cl
orb %al, %cl
jne 0x4448f
movq (%rbx), %rax
leaq -0xa8(%rbp), %rdi
movq %rbx, (%rdi)
movq 0x20(%rax), %rax
movl %r12d, %ecx
shlq $0x5, %rcx
movq (%rax,%rcx), %rdx
movq %rdx, 0x10(%rdi)
movq 0x18(%rax,%rcx), %rax
movq %rax, 0x8(%rdi)
leaq 0x38b57(%rip), %rax     # 0x7cfcd
movq %rax, 0x18(%rdi)
movq %r15, 0x20(%rdi)
movq -0x48(%rbp), %rsi
callq 0x4bb48
testl %eax, %eax
jne 0x443c1
movq %rbx, %rdi
movq -0x48(%rbp), %rsi
callq 0x4baec
testq %rax, %rax
je 0x44539
testb $0x10, 0x46(%rax)
jne 0x4455a
movq %rax, -0x60(%rbp)
movq %r14, %rdi
movq %r15, -0x80(%rbp)
movq %r15, %rsi
callq 0x45df3
testq %rax, %rax
je 0x443c1
movq %rax, %r15
movq %rbx, %rdi
movq %rax, %rsi
callq 0x45f34
testl %eax, %eax
jne 0x443c4
movq 0x20(%r14), %rcx
movl %r12d, %eax
shlq $0x5, %rax
movq %rax, -0x78(%rbp)
movq %rcx, -0x50(%rbp)
movq 0x18(%rcx,%rax), %rdi
xorl %edx, %edx
cmpb $0x0, (%r15,%rdx)
leaq 0x1(%rdx), %rdx
jne 0x444fa
addq $0x38, %rdi
decl %edx
andl $0x3fffffff, %edx       # imm = 0x3FFFFFFF
movq %r15, %rsi
callq 0x3396f
testq %rax, %rax
je 0x44566
cmpl $0x0, -0x38(%rbp)
movq -0x30(%rbp), %r13
je 0x445d4
movq %rbx, %rdi
movl %r12d, %esi
callq 0x45ff7
jmp 0x44552
cmpb $0x1, 0x98(%r14)
movq -0x30(%rbp), %r13
jne 0x4454f
movb $0x1, 0x9a(%r14)
xorl %r15d, %r15d
xorl %r12d, %r12d
jmp 0x443cb
leaq 0x38018(%rip), %rsi     # 0x7c579
jmp 0x442ed
movq -0x60(%rbp), %r12
movq (%r12), %rdi
leaq 0x36877(%rip), %rsi     # 0x7adec
movq %rdi, -0x38(%rbp)
movl $0x7, %edx
callq 0x9454
testl %eax, %eax
je 0x445f1
movq 0x18(%r12), %rax
testq %rax, %rax
sete %cl
movl -0x3c(%rbp), %esi
cmpl $0x30, %esi
sete %dl
orb %cl, %dl
jne 0x4460d
cmpl $0x22, %esi
leaq 0x3805e(%rip), %rax     # 0x7c607
leaq 0x3805e(%rip), %rdx     # 0x7c60e
cmoveq %rax, %rdx
leaq 0x38027(%rip), %rsi     # 0x7c5e2
xorl %r12d, %r12d
movq %rbx, %rdi
movq -0x48(%rbp), %rcx
xorl %r8d, %r8d
xorl %eax, %eax
callq 0x11724
jmp 0x443c7
leaq 0x37fc7(%rip), %rsi     # 0x7c5a2
xorl %r12d, %r12d
movq %rbx, %rdi
movq -0x80(%rbp), %rdx
xorl %eax, %eax
callq 0x11724
jmp 0x443cb
leaq 0x37fc4(%rip), %rsi     # 0x7c5bc
xorl %r12d, %r12d
movq %rbx, %rdi
xorl %eax, %eax
callq 0x11724
incl 0x50(%rbx)
jmp 0x443c7
testq %rax, %rax
setne %al
cmpl $0x30, %esi
setne %cl
orb %al, %cl
jne 0x4463c
leaq 0x37ff0(%rip), %rsi     # 0x7c614
xorl %r12d, %r12d
movq %rbx, %rdi
movq -0x48(%rbp), %rdx
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x11724
jmp 0x443c7
movl %esi, -0x3c(%rbp)
movq 0x68(%r12), %rax
testq %rax, %rax
je 0x44672
movl 0x28(%r14), %ecx
testl %ecx, %ecx
jle 0x4467a
movq -0x50(%rbp), %rdx
addq $0x18, %rdx
xorl %r12d, %r12d
cmpq %rax, (%rdx)
je 0x4467d
incq %r12
addq $0x20, %rdx
cmpq %r12, %rcx
jne 0x4465c
movl %ecx, %r12d
jmp 0x4467d
movl $0xfff0bdc0, %r12d      # imm = 0xFFF0BDC0
jmp 0x4467d
xorl %r12d, %r12d
movq -0x50(%rbp), %rdx
movq -0x38(%rbp), %rcx
movslq %r12d, %rax
shlq $0x5, %rax
movq (%rdx,%rax), %r8
movq %r8, -0x38(%rbp)
testl %r13d, %r13d
je 0x4469d
movq 0x20(%rdx), %r8
xorl %eax, %eax
cmpl $0x1, %r12d
setne %al
testl %r13d, %r13d
leal 0x5(%rax,%rax), %eax
movl $0x5, %esi
cmovel %eax, %esi
movq %rbx, %rdi
movq %r15, %rdx
callq 0x45d75
testl %eax, %eax
jne 0x443c4
cmpl $0x1, %r12d
leaq 0x35846(%rip), %rax     # 0x79f19
leaq 0x35852(%rip), %rdx     # 0x79f2c
cmoveq %rax, %rdx
xorl %r12d, %r12d
movq %rbx, %rdi
movl $0x12, %esi
xorl %ecx, %ecx
movq -0x38(%rbp), %r8
callq 0x45d75
testl %eax, %eax
jne 0x443c7
movq %r14, %rdi
movl $0x48, %esi
callq 0x115e9
testq %rax, %rax
je 0x443c4
movq %rax, %r12
movl -0x3c(%rbp), %r13d
cmpl $0x30, %r13d
sete -0x38(%rbp)
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movups %xmm0, 0x30(%rax)
movups %xmm0, 0x20(%rax)
movups %xmm0, 0x10(%rax)
movq $0x0, 0x40(%rax)
movq %r15, (%rax)
movq -0x48(%rbp), %rax
movq 0x18(%rax), %rsi
movq %r14, %rdi
callq 0x1010d
movq %rax, 0x8(%r12)
movq 0x20(%r14), %rax
movq -0x78(%rbp), %rcx
movq 0x18(%rax,%rcx), %rax
movq %rax, 0x28(%r12)
movq -0x60(%rbp), %rax
movq 0x68(%rax), %rax
movq %rax, 0x30(%r12)
movl -0x54(%rbp), %eax
movb %al, 0x10(%r12)
cmpl $0x22, %r13d
sete %al
orb -0x38(%rbp), %al
movb $0x2, %cl
subb %al, %cl
movb %cl, 0x11(%r12)
xorl %r15d, %r15d
movq %r14, %rdi
movq -0x68(%rbp), %rsi
movl $0x1, %edx
xorl %ecx, %ecx
callq 0x48163
movq %rax, 0x18(%r12)
movq %r14, %rdi
movq -0x30(%rbp), %r13
movq %r13, %rsi
callq 0x488c4
movq %rax, 0x20(%r12)
movq %r12, 0x240(%rbx)
jmp 0x443cb