// File: /workspace/github_c_makefile_star2_O3/barabo[P]advanced-shell-history/src/sqlite3.c
// Function: fkLookupParent
static void fkLookupParent(
  Parse *pParse,        /* Parse context */
  int iDb,              /* Index of database housing pTab */
  Table *pTab,          /* Parent table of FK pFKey */
  Index *pIdx,          /* Unique index on parent key columns in pTab */
  FKey *pFKey,          /* Foreign key constraint */
  int *aiCol,           /* Map from parent key columns to child table columns */
  int regData,          /* Address of array containing child table row */
  int nIncr,            /* Increment constraint counter by this */
  int isIgnore          /* If true, pretend pTab contains all NULL values */
){
  int i;                                    /* Iterator variable */
  Vdbe *v = sqlite3GetVdbe(pParse);         /* Vdbe to add code to */
  int iCur = pParse->nTab - 1;              /* Cursor number to use */
  int iOk = sqlite3VdbeMakeLabel(v);        /* jump here if parent key found */

  /* If nIncr is less than zero, then check at runtime if there are any
  ** outstanding constraints to resolve. If there are not, there is no need
  ** to check if deleting this row resolves any outstanding violations.
  **
  ** Check if any of the key columns in the child table row are NULL. If 
  ** any are, then the constraint is considered satisfied. No need to 
  ** search for a matching row in the parent table.  */
  if( nIncr<0 ){
    sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
  }
  for(i=0; i<pFKey->nCol; i++){
    int iReg = aiCol[i] + regData + 1;
    sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk);
  }

  if( isIgnore==0 ){
    if( pIdx==0 ){
      /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY
      ** column of the parent table (table pTab).  */
      int iMustBeInt;               /* Address of MustBeInt instruction */
      int regTemp = sqlite3GetTempReg(pParse);
  
      /* Invoke MustBeInt to coerce the child key value to an integer (i.e. 
      ** apply the affinity of the parent key). If this fails, then there
      ** is no matching parent key. Before using MustBeInt, make a copy of
      ** the value. Otherwise, the value inserted into the child key column
      ** will have INTEGER affinity applied to it, which may not be correct.  */
      sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp);
      iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0);
  
      /* If the parent table is the same as the child table, and we are about
      ** to increment the constraint-counter (i.e. this is an INSERT operation),
      ** then check if the row being inserted matches itself. If so, do not
      ** increment the constraint-counter.  */
      if( pTab==pFKey->pFrom && nIncr==1 ){
        sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp);
      }
  
      sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
      sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp);
      sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
      sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
      sqlite3VdbeJumpHere(v, iMustBeInt);
      sqlite3ReleaseTempReg(pParse, regTemp);
    }else{
      int nCol = pFKey->nCol;
      int regTemp = sqlite3GetTempRange(pParse, nCol);
      int regRec = sqlite3GetTempReg(pParse);
      KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
  
      sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
      sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
      for(i=0; i<nCol; i++){
        sqlite3VdbeAddOp2(v, OP_Copy, aiCol[i]+1+regData, regTemp+i);
      }
  
      /* If the parent table is the same as the child table, and we are about
      ** to increment the constraint-counter (i.e. this is an INSERT operation),
      ** then check if the row being inserted matches itself. If so, do not
      ** increment the constraint-counter. 
      **
      ** If any of the parent-key values are NULL, then the row cannot match 
      ** itself. So set JUMPIFNULL to make sure we do the OP_Found if any
      ** of the parent-key values are NULL (at this point it is known that
      ** none of the child key values are).
      */
      if( pTab==pFKey->pFrom && nIncr==1 ){
        int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1;
        for(i=0; i<nCol; i++){
          int iChild = aiCol[i]+1+regData;
          int iParent = pIdx->aiColumn[i]+1+regData;
          assert( aiCol[i]!=pTab->iPKey );
          if( pIdx->aiColumn[i]==pTab->iPKey ){
            /* The parent key is a composite key that includes the IPK column */
            iParent = regData;
          }
          sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent);
          sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
        }
        sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
      }
  
      sqlite3VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec);
      sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT);
      sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);
  
      sqlite3ReleaseTempReg(pParse, regRec);
      sqlite3ReleaseTempRange(pParse, regTemp, nCol);
    }
  }

  if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs)
   && !pParse->pToplevel 
   && !pParse->isMultiWrite 
  ){
    /* Special case: If this is an INSERT statement that will insert exactly
    ** one row into the table, raise a constraint immediately instead of
    ** incrementing a counter. This is necessary as the VM code is being
    ** generated for will not open a statement transaction.  */
    assert( nIncr==1 );
    sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
        OE_Abort, "foreign key constraint failed", P4_STATIC
    );
  }else{
    if( nIncr>0 && pFKey->isDeferred==0 ){
      sqlite3ParseToplevel(pParse)->mayAbort = 1;
    }
    sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
  }

  sqlite3VdbeResolveLabel(v, iOk);
  sqlite3VdbeAddOp1(v, OP_Close, iCur);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %r9, %r13
movq %r8, %r14
movq %rcx, -0x80(%rbp)
movq %rdx, -0x88(%rbp)
movl %esi, -0x40(%rbp)
movq %rdi, %rbx
movl 0x20(%rbp), %eax
movl %eax, -0x3c(%rbp)
movl 0x18(%rbp), %r12d
movl 0x10(%rbp), %eax
movq %rax, -0x60(%rbp)
callq 0x45ece
movq %rbx, -0x58(%rbp)
movl 0x54(%rbx), %ebx
movq %rax, -0x38(%rbp)
movq %rax, %rdi
callq 0x4c5eb
movl %eax, %r15d
testl %r12d, %r12d
jns 0x5e1e1
movzbl 0x2c(%r14), %edx
movq -0x38(%rbp), %rdi
movl $0x7c, %esi
movl %r15d, %ecx
xorl %r8d, %r8d
callq 0x45f15
movq %r14, -0x78(%rbp)
movl 0x28(%r14), %edx
testl %edx, %edx
jle 0x5e242
movl %r12d, -0x44(%rbp)
movl %ebx, -0x48(%rbp)
movq -0x60(%rbp), %rax
leal 0x1(%rax), %ebx
movl %r15d, -0x2c(%rbp)
xorl %r15d, %r15d
movq %r13, %r12
movq -0x38(%rbp), %r13
movq -0x78(%rbp), %r14
movl (%r12,%r15,4), %edx
addl %ebx, %edx
movq %r13, %rdi
movl $0x49, %esi
movl -0x2c(%rbp), %ecx
xorl %r8d, %r8d
callq 0x45f15
incq %r15
movslq 0x28(%r14), %rdx
cmpq %rdx, %r15
jl 0x5e20d
movl -0x48(%rbp), %ebx
movl -0x2c(%rbp), %r15d
movl -0x44(%rbp), %eax
movq %r12, %r13
movl %eax, %r12d
decl %ebx
cmpl $0x0, -0x3c(%rbp)
movq -0x58(%rbp), %rdi
je 0x5e2e3
movq -0x78(%rbp), %rax
movzbl 0x2c(%rax), %edx
testl %edx, %edx
jne 0x5e292
movq (%rdi), %rax
testb $0x1, 0x2f(%rax)
jne 0x5e27b
cmpq $0x0, 0x1d8(%rdi)
jne 0x5e27b
cmpb $0x0, 0x23(%rdi)
je 0x5e6d1
testl %r12d, %r12d
jle 0x5e292
movq 0x1d8(%rdi), %rax
testq %rax, %rax
cmoveq %rdi, %rax
movb $0x1, 0x24(%rax)
movq -0x38(%rbp), %rdi
movl $0x7b, %esi
movl %r12d, %ecx
xorl %r8d, %r8d
callq 0x45f15
testl %r15d, %r15d
movq -0x38(%rbp), %rdi
jns 0x5e2c4
movq 0x40(%rdi), %rax
testq %rax, %rax
je 0x5e2c4
notl %r15d
movl 0x34(%rdi), %ecx
movl %r15d, %edx
movl %ecx, (%rax,%rdx,4)
movl $0x36, %esi
movl %ebx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x45f15
cmpq $0x0, -0x80(%rbp)
je 0x5e302
movl 0x48(%rdi), %eax
subl %edx, %eax
jge 0x5e31f
movl 0x58(%rdi), %eax
leal 0x1(%rax), %ecx
movq %rcx, -0x68(%rbp)
addl %edx, %eax
movl %eax, 0x58(%rdi)
jmp 0x5e32e
movb 0x1f(%rdi), %al
testb %al, %al
je 0x5e563
decb %al
movb %al, 0x1f(%rdi)
movzbl %al, %eax
movl 0x28(%rdi,%rax,4), %r14d
jmp 0x5e56e
movl 0x4c(%rdi), %ecx
movq %rcx, -0x68(%rbp)
addl %edx, %ecx
movl %ecx, 0x4c(%rdi)
movl %eax, 0x48(%rdi)
movl %r12d, -0x44(%rbp)
movl %r15d, -0x2c(%rbp)
movb 0x1f(%rdi), %al
testb %al, %al
movq %rdx, -0x50(%rbp)
je 0x5e352
decb %al
movb %al, 0x1f(%rdi)
movzbl %al, %eax
movl 0x28(%rdi,%rax,4), %eax
movl %eax, -0x6c(%rbp)
jmp 0x5e35d
movl 0x58(%rdi), %eax
incl %eax
movl %eax, -0x6c(%rbp)
movl %eax, 0x58(%rdi)
movq -0x80(%rbp), %r15
movq %r15, %rsi
callq 0x4c2fa
movq %rax, %r14
movl 0x50(%r15), %ecx
movq -0x38(%rbp), %r15
movq %r15, %rdi
movl $0x30, %esi
movl %ebx, -0x48(%rbp)
movl %ebx, %edx
movl -0x40(%rbp), %r8d
callq 0x45f15
movq %r15, %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movq %r14, %rdx
movl $0xfffffff0, %ecx       # imm = 0xFFFFFFF0
callq 0x11a9f
cmpl $0x0, -0x50(%rbp)
movq %r15, %r14
jle 0x5e3df
movq -0x60(%rbp), %rax
incl %eax
movl %eax, -0x3c(%rbp)
movl -0x50(%rbp), %r12d
movl -0x68(%rbp), %ebx
xorl %r15d, %r15d
movl (%r13,%r15,4), %edx
addl -0x3c(%rbp), %edx
leal (%rbx,%r15), %ecx
movq %r14, %rdi
movl $0x1c, %esi
xorl %r8d, %r8d
callq 0x45f15
incq %r15
cmpq %r15, %r12
jne 0x5e3bb
movl -0x44(%rbp), %r12d
cmpl $0x1, %r12d
movq %r14, %rcx
movl -0x48(%rbp), %ebx
movq -0x88(%rbp), %r14
jne 0x5e4b1
movq -0x78(%rbp), %rax
cmpq %r14, (%rax)
jne 0x5e4b1
cmpl $0x0, -0x50(%rbp)
jle 0x5e497
movl 0x34(%rcx), %eax
movq -0x50(%rbp), %rcx
addl %ecx, %eax
incl %eax
movl %eax, -0x3c(%rbp)
movq -0x60(%rbp), %rax
incl %eax
movl %eax, -0x40(%rbp)
movl %ecx, %eax
movq %rax, -0x90(%rbp)
xorl %r15d, %r15d
movl (%r13,%r15,4), %edx
addl -0x40(%rbp), %edx
movq -0x80(%rbp), %rax
movq 0x8(%rax), %rax
movl (%rax,%r15,4), %eax
leal 0x1(%rax), %r8d
movswl 0x40(%r14), %ecx
cmpl %ecx, %eax
movl $0x0, %eax
cmovel %eax, %r8d
addl -0x60(%rbp), %r8d
movq -0x38(%rbp), %rdi
movl $0x4b, %esi
movl -0x3c(%rbp), %ecx
callq 0x45f15
movq -0x38(%rbp), %rcx
movq 0x8(%rcx), %rax
testq %rax, %rax
je 0x5e48b
movslq 0x34(%rcx), %rcx
leaq (%rcx,%rcx,2), %rcx
movb $0x8, -0x15(%rax,%rcx,8)
incq %r15
cmpq %r15, -0x90(%rbp)
jne 0x5e434
movq -0x38(%rbp), %rdi
movl $0xe, %esi
xorl %edx, %edx
movl -0x2c(%rbp), %ecx
xorl %r8d, %r8d
callq 0x45f15
movq -0x38(%rbp), %rcx
movq %rcx, %r13
movq %rcx, %rdi
movl $0x2b, %esi
movq -0x68(%rbp), %rdx
movq %rdx, -0x68(%rbp)
movq -0x50(%rbp), %rcx
movl -0x6c(%rbp), %r14d
movl %r14d, %r8d
callq 0x45f15
movq %r13, %rdi
movq -0x80(%rbp), %rsi
callq 0x4c9e0
movq %r13, %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x11a9f
movq %r13, %rdi
movl $0x3d, %esi
movl %ebx, %edx
movl -0x2c(%rbp), %r15d
movl %r15d, %ecx
movl %r14d, %r8d
callq 0x45f15
movq %r13, %rdi
movl %eax, %esi
xorl %edx, %edx
movl $0xfffffff2, %ecx       # imm = 0xFFFFFFF2
callq 0x11a9f
testl %r14d, %r14d
movq -0x58(%rbp), %rdx
je 0x5e69f
movzbl 0x1f(%rdx), %eax
cmpq $0x7, %rax
ja 0x5e69f
xorl %ecx, %ecx
cmpl %r14d, 0x84(%rdx,%rcx)
je 0x5e69a
addq $0x18, %rcx
cmpl $0xf0, %ecx
jne 0x5e539
leal 0x1(%rax), %ecx
movb %cl, 0x1f(%rdx)
movl %r14d, 0x28(%rdx,%rax,4)
jmp 0x5e69f
movl 0x58(%rdi), %r14d
incl %r14d
movl %r14d, 0x58(%rdi)
movl (%r13), %eax
movq -0x60(%rbp), %rcx
leal (%rcx,%rax), %edx
incl %edx
movq -0x38(%rbp), %r13
movq %r13, %rdi
movl $0x1d, %esi
movl %r14d, %ecx
xorl %r8d, %r8d
callq 0x45f15
movq %r13, %rdi
movl $0x21, %esi
movl %r14d, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x45f15
movl %eax, -0x2c(%rbp)
cmpl $0x1, %r12d
jne 0x5e5d8
movq -0x78(%rbp), %rax
movq -0x88(%rbp), %rcx
cmpq %rcx, (%rax)
jne 0x5e5d8
movq -0x38(%rbp), %rdi
movl $0x4c, %esi
movq -0x60(%rbp), %rdx
movl %r15d, %ecx
movl %r14d, %r8d
callq 0x45f15
movq -0x58(%rbp), %rdi
movl %ebx, %esi
movl -0x40(%rbp), %edx
movq -0x88(%rbp), %rcx
movl $0x30, %r8d
callq 0x45fa0
movq -0x38(%rbp), %r13
movq %r13, %rdi
movl $0x3f, %esi
movl %ebx, %edx
xorl %ecx, %ecx
movl %r14d, %r8d
callq 0x45f15
movq %r13, %rdi
movl $0xe, %esi
xorl %edx, %edx
movl %r15d, %ecx
xorl %r8d, %r8d
callq 0x45f15
movl 0x34(%r13), %eax
cmpl $0x2, %eax
jl 0x5e638
leal -0x2(%rax), %ecx
movq 0x8(%r13), %rdx
leaq (%rcx,%rcx,2), %rcx
movl %eax, 0x8(%rdx,%rcx,8)
movl -0x2c(%rbp), %esi
testl %esi, %esi
sets %cl
cmpl %esi, %eax
setbe %dl
orb %cl, %dl
jne 0x5e657
movq 0x8(%r13), %rcx
movl %esi, %edx
leaq (%rdx,%rdx,2), %rdx
movl %eax, 0x8(%rcx,%rdx,8)
testl %r14d, %r14d
movq -0x58(%rbp), %rdi
je 0x5e252
movzbl 0x1f(%rdi), %eax
cmpq $0x7, %rax
ja 0x5e252
xorl %ecx, %ecx
cmpl %r14d, 0x84(%rdi,%rcx)
je 0x5e6f2
addq $0x18, %rcx
cmpl $0xf0, %ecx
jne 0x5e674
leal 0x1(%rax), %ecx
movb %cl, 0x1f(%rdi)
movl %r14d, 0x28(%rdi,%rax,4)
jmp 0x5e252
movb $0x1, 0x7c(%rdx,%rcx)
movq -0x58(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq %rsi, %r13
movq -0x50(%rbp), %r14
movl %r14d, %edx
callq 0x4e564
movq -0x58(%rbp), %rdi
cmpl %r14d, 0x48(%rdi)
jge 0x5e252
movl %r14d, 0x48(%rdi)
movl %r13d, 0x4c(%rdi)
jmp 0x5e252
leaq 0x1b1b2(%rip), %rcx     # 0x7988a
movl $0x313, %esi            # imm = 0x313
movl $0x2, %edx
movl $0xfffffffe, %r8d       # imm = 0xFFFFFFFE
callq 0x4c573
jmp 0x5e2a6
movb $0x1, 0x7c(%rdi,%rcx)
jmp 0x5e252