// File: /workspace/github_c_makefile_star2_O0/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
subq $0x90, %rsp
movl 0x20(%rbp), %eax
movl 0x18(%rbp), %eax
movl 0x10(%rbp), %eax
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq -0x8(%rbp), %rdi
callq 0x5e000
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rax
movl 0x54(%rax), %eax
subl $0x1, %eax
movl %eax, -0x44(%rbp)
movq -0x40(%rbp), %rdi
callq 0x67890
movl %eax, -0x48(%rbp)
cmpl $0x0, 0x18(%rbp)
jge 0x7e910
movq -0x40(%rbp), %rdi
movq -0x28(%rbp), %rax
movzbl 0x2c(%rax), %edx
movl -0x48(%rbp), %ecx
movl $0x7c, %esi
callq 0x5e0c0
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
movq -0x28(%rbp), %rcx
cmpl 0x28(%rcx), %eax
jge 0x7e956
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rcx
movl (%rax,%rcx,4), %eax
addl 0x10(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
movq -0x40(%rbp), %rdi
movl -0x4c(%rbp), %edx
movl -0x48(%rbp), %ecx
movl $0x49, %esi
callq 0x5e0c0
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x7e917
cmpl $0x0, 0x20(%rbp)
jne 0x7ec4e
cmpq $0x0, -0x20(%rbp)
jne 0x7ea54
movq -0x8(%rbp), %rdi
callq 0x66a70
movl %eax, -0x54(%rbp)
movq -0x40(%rbp), %rdi
movq -0x30(%rbp), %rax
movl (%rax), %edx
addl $0x1, %edx
addl 0x10(%rbp), %edx
movl -0x54(%rbp), %ecx
movl $0x1d, %esi
callq 0x5e0c0
movq -0x40(%rbp), %rdi
movl -0x54(%rbp), %edx
movl $0x21, %esi
xorl %ecx, %ecx
callq 0x5e0c0
movl %eax, -0x50(%rbp)
movq -0x18(%rbp), %rax
movq -0x28(%rbp), %rcx
cmpq (%rcx), %rax
jne 0x7e9d5
cmpl $0x1, 0x18(%rbp)
jne 0x7e9d5
movq -0x40(%rbp), %rdi
movl 0x10(%rbp), %edx
movl -0x48(%rbp), %ecx
movl -0x54(%rbp), %r8d
movl $0x4c, %esi
callq 0x5e0f0
movq -0x8(%rbp), %rdi
movl -0x44(%rbp), %esi
movl -0xc(%rbp), %edx
movq -0x18(%rbp), %rcx
movl $0x30, %r8d
callq 0x5e480
movq -0x40(%rbp), %rdi
movl -0x44(%rbp), %edx
movl -0x54(%rbp), %r8d
movl $0x3f, %esi
xorl %ecx, %ecx
callq 0x5e0f0
movq -0x40(%rbp), %rdi
movl -0x48(%rbp), %ecx
movl $0xe, %esi
xorl %edx, %edx
callq 0x5e0c0
movq -0x40(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x40(%rbp), %rdi
callq 0x5e520
movq -0x80(%rbp), %rdi
movl %eax, %esi
subl $0x2, %esi
callq 0x5e090
movq -0x40(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x5e090
movq -0x8(%rbp), %rdi
movl -0x54(%rbp), %esi
callq 0x66ac0
jmp 0x7ec4c
movq -0x28(%rbp), %rax
movl 0x28(%rax), %eax
movl %eax, -0x58(%rbp)
movq -0x8(%rbp), %rdi
movl -0x58(%rbp), %esi
callq 0x67c30
movl %eax, -0x5c(%rbp)
movq -0x8(%rbp), %rdi
callq 0x66a70
movl %eax, -0x60(%rbp)
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x67540
movq %rax, -0x68(%rbp)
movq -0x40(%rbp), %rdi
movl -0x44(%rbp), %edx
movq -0x20(%rbp), %rax
movl 0x50(%rax), %ecx
movl -0xc(%rbp), %r8d
movl $0x30, %esi
callq 0x5e0f0
movq -0x40(%rbp), %rdi
movq -0x68(%rbp), %rdx
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movl $0xfffffff0, %ecx       # imm = 0xFFFFFFF0
callq 0x13c20
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x58(%rbp), %eax
jge 0x7eafc
movq -0x40(%rbp), %rdi
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rcx
movl (%rax,%rcx,4), %edx
addl $0x1, %edx
addl 0x10(%rbp), %edx
movl -0x5c(%rbp), %ecx
addl -0x34(%rbp), %ecx
movl $0x1c, %esi
callq 0x5e0c0
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x7eac4
movq -0x18(%rbp), %rax
movq -0x28(%rbp), %rcx
cmpq (%rcx), %rax
jne 0x7ebd0
cmpl $0x1, 0x18(%rbp)
jne 0x7ebd0
movq -0x40(%rbp), %rdi
callq 0x5e520
addl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x58(%rbp), %eax
jge 0x7ebbd
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rcx
movl (%rax,%rcx,4), %eax
addl $0x1, %eax
addl 0x10(%rbp), %eax
movl %eax, -0x70(%rbp)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x34(%rbp), %rcx
movl (%rax,%rcx,4), %eax
addl $0x1, %eax
addl 0x10(%rbp), %eax
movl %eax, -0x74(%rbp)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x34(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movq -0x18(%rbp), %rcx
movswl 0x40(%rcx), %ecx
cmpl %ecx, %eax
jne 0x7eb89
movl 0x10(%rbp), %eax
movl %eax, -0x74(%rbp)
movq -0x40(%rbp), %rdi
movl -0x70(%rbp), %edx
movl -0x6c(%rbp), %ecx
movl -0x74(%rbp), %r8d
movl $0x4b, %esi
callq 0x5e0f0
movq -0x40(%rbp), %rdi
movl $0x8, %esi
callq 0x5e540
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x7eb30
movq -0x40(%rbp), %rdi
movl -0x48(%rbp), %ecx
movl $0xe, %esi
xorl %edx, %edx
callq 0x5e0c0
movq -0x40(%rbp), %rdi
movl -0x5c(%rbp), %edx
movl -0x58(%rbp), %ecx
movl -0x60(%rbp), %r8d
movl $0x2b, %esi
callq 0x5e0f0
movq -0x40(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x40(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x67d80
movq -0x88(%rbp), %rdi
movq %rax, %rdx
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
xorl %ecx, %ecx
callq 0x13c20
movq -0x40(%rbp), %rdi
movl -0x44(%rbp), %edx
movl -0x48(%rbp), %ecx
movl -0x60(%rbp), %r8d
movl $0x3d, %esi
xorl %r9d, %r9d
callq 0x6b080
movq -0x8(%rbp), %rdi
movl -0x60(%rbp), %esi
callq 0x66ac0
movq -0x8(%rbp), %rdi
movl -0x5c(%rbp), %esi
movl -0x58(%rbp), %edx
callq 0x67e90
jmp 0x7ec4e
movq -0x28(%rbp), %rax
cmpb $0x0, 0x2c(%rax)
jne 0x7eca6
movq -0x8(%rbp), %rax
movq (%rax), %rax
movl 0x2c(%rax), %eax
andl $0x1000000, %eax        # imm = 0x1000000
cmpl $0x0, %eax
jne 0x7eca6
movq -0x8(%rbp), %rax
cmpq $0x0, 0x1d8(%rax)
jne 0x7eca6
movq -0x8(%rbp), %rax
cmpb $0x0, 0x23(%rax)
jne 0x7eca6
movq -0x8(%rbp), %rdi
movl $0x313, %esi            # imm = 0x313
movl $0x2, %edx
leaq 0x2f6e8(%rip), %rcx     # 0xae381
movl $0xfffffffe, %r8d       # imm = 0xFFFFFFFE
callq 0x67830
jmp 0x7ed0a
cmpl $0x0, 0x18(%rbp)
jle 0x7ecf1
movq -0x28(%rbp), %rax
movzbl 0x2c(%rax), %eax
cmpl $0x0, %eax
jne 0x7ecf1
movq -0x8(%rbp), %rax
cmpq $0x0, 0x1d8(%rax)
je 0x7ecdb
movq -0x8(%rbp), %rax
movq 0x1d8(%rax), %rax
movq %rax, -0x90(%rbp)
jmp 0x7ece6
movq -0x8(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
movb $0x1, 0x24(%rax)
movq -0x40(%rbp), %rdi
movq -0x28(%rbp), %rax
movzbl 0x2c(%rax), %edx
movl 0x18(%rbp), %ecx
movl $0x7b, %esi
callq 0x5e0c0
movq -0x40(%rbp), %rdi
movl -0x48(%rbp), %esi
callq 0x677f0
movq -0x40(%rbp), %rdi
movl -0x44(%rbp), %edx
movl $0x36, %esi
callq 0x5ecf0
addq $0x90, %rsp
popq %rbp
retq