// File: /workspace/github_c_makefile_star2_O1/barabo[P]advanced-shell-history/src/sqlite3.c
// Function: sqlite3CreateForeignKey
SQLITE_PRIVATE void sqlite3CreateForeignKey(
  Parse *pParse,       /* Parsing context */
  ExprList *pFromCol,  /* Columns in this table that point to other table */
  Token *pTo,          /* Name of the other table */
  ExprList *pToCol,    /* Columns in the other table */
  int flags            /* Conflict resolution algorithms. */
){
  sqlite3 *db = pParse->db;
#ifndef SQLITE_OMIT_FOREIGN_KEY
  FKey *pFKey = 0;
  FKey *pNextTo;
  Table *p = pParse->pNewTable;
  int nByte;
  int i;
  int nCol;
  char *z;

  assert( pTo!=0 );
  if( p==0 || IN_DECLARE_VTAB ) goto fk_end;
  if( pFromCol==0 ){
    int iCol = p->nCol-1;
    if( NEVER(iCol<0) ) goto fk_end;
    if( pToCol && pToCol->nExpr!=1 ){
      sqlite3ErrorMsg(pParse, "foreign key on %s"
         " should reference only one column of table %T",
         p->aCol[iCol].zName, pTo);
      goto fk_end;
    }
    nCol = 1;
  }else if( pToCol && pToCol->nExpr!=pFromCol->nExpr ){
    sqlite3ErrorMsg(pParse,
        "number of columns in foreign key does not match the number of "
        "columns in the referenced table");
    goto fk_end;
  }else{
    nCol = pFromCol->nExpr;
  }
  nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1;
  if( pToCol ){
    for(i=0; i<pToCol->nExpr; i++){
      nByte += sqlite3Strlen30(pToCol->a[i].zName) + 1;
    }
  }
  pFKey = sqlite3DbMallocZero(db, nByte );
  if( pFKey==0 ){
    goto fk_end;
  }
  pFKey->pFrom = p;
  pFKey->pNextFrom = p->pFKey;
  z = (char*)&pFKey->aCol[nCol];
  pFKey->zTo = z;
  memcpy(z, pTo->z, pTo->n);
  z[pTo->n] = 0;
  sqlite3Dequote(z);
  z += pTo->n+1;
  pFKey->nCol = nCol;
  if( pFromCol==0 ){
    pFKey->aCol[0].iFrom = p->nCol-1;
  }else{
    for(i=0; i<nCol; i++){
      int j;
      for(j=0; j<p->nCol; j++){
        if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){
          pFKey->aCol[i].iFrom = j;
          break;
        }
      }
      if( j>=p->nCol ){
        sqlite3ErrorMsg(pParse, 
          "unknown column \"%s\" in foreign key definition", 
          pFromCol->a[i].zName);
        goto fk_end;
      }
    }
  }
  if( pToCol ){
    for(i=0; i<nCol; i++){
      int n = sqlite3Strlen30(pToCol->a[i].zName);
      pFKey->aCol[i].zCol = z;
      memcpy(z, pToCol->a[i].zName, n);
      z[n] = 0;
      z += n+1;
    }
  }
  pFKey->isDeferred = 0;
  pFKey->aAction[0] = (u8)(flags & 0xff);            /* ON DELETE action */
  pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff);    /* ON UPDATE action */

  assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) );
  pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, 
      pFKey->zTo, sqlite3Strlen30(pFKey->zTo), (void *)pFKey
  );
  if( pNextTo==pFKey ){
    db->mallocFailed = 1;
    goto fk_end;
  }
  if( pNextTo ){
    assert( pNextTo->pPrevTo==0 );
    pFKey->pNextTo = pNextTo;
    pNextTo->pPrevTo = pFKey;
  }

  /* Link the foreign key to the table as the last step.
  */
  p->pFKey = pFKey;
  pFKey = 0;

fk_end:
  sqlite3DbFree(db, pFKey);
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
  sqlite3ExprListDelete(db, pFromCol);
  sqlite3ExprListDelete(db, pToCol);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rcx, %r14
movq %rdx, %r12
movq (%rdi), %r15
movq 0x238(%rdi), %rdx
testq %rdx, %rdx
movq %rsi, -0x58(%rbp)
je 0x3afea
movq %rdi, %r13
cmpb $0x0, 0x201(%rdi)
je 0x3b01c
xorl %ebx, %ebx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x9c3a
movq %r15, %rdi
movq -0x58(%rbp), %rsi
callq 0x3410b
movq %r15, %rdi
movq %r14, %rsi
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3410b
testq %rsi, %rsi
je 0x3b236
testq %r14, %r14
je 0x3b035
movl (%r14), %eax
cmpl (%rsi), %eax
jne 0x3b294
movl (%rsi), %ecx
movl %ecx, -0x30(%rbp)
movl %r8d, -0x64(%rbp)
movq %r15, -0x48(%rbp)
movl %ecx, %eax
shll $0x4, %eax
movl 0x8(%r12), %ecx
leal (%rax,%rcx), %r15d
addl $0x41, %r15d
testq %r14, %r14
movq %rdx, -0x38(%rbp)
je 0x3b0a6
movslq (%r14), %rax
testq %rax, %rax
jle 0x3b0a6
movq 0x8(%r14), %rcx
xorl %edx, %edx
movq %rdx, %rsi
shlq $0x5, %rsi
movq 0x8(%rcx,%rsi), %rdi
testq %rdi, %rdi
je 0x3b096
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
incl %esi
cmpb $0x0, (%rdi)
leaq 0x1(%rdi), %rdi
jne 0x3b081
andl $0x3fffffff, %esi       # imm = 0x3FFFFFFF
incl %esi
jmp 0x3b09b
movl $0x1, %esi
addl %esi, %r15d
incq %rdx
cmpq %rax, %rdx
jne 0x3b06b
movq -0x48(%rbp), %rdi
movl %r15d, %esi
callq 0x115e9
testq %rax, %rax
je 0x3b290
movq %rax, %rbx
movslq %r15d, %rdx
movq %rax, %rdi
xorl %esi, %esi
callq 0x8200
movq -0x38(%rbp), %rax
movq %rax, (%rbx)
movq 0x20(%rax), %rax
movq %rax, 0x8(%rbx)
leaq 0x40(%rbx), %rax
movq %rax, -0x60(%rbp)
movslq -0x30(%rbp), %rax
shlq $0x4, %rax
leaq (%rbx,%rax), %r15
addq $0x40, %r15
movq %r15, 0x10(%rbx)
movq (%r12), %rsi
movl 0x8(%r12), %edx
movq %r15, %rdi
callq 0x82f0
movl 0x8(%r12), %eax
movb $0x0, (%rax,%r15)
movq %r15, %rdi
callq 0x45e50
movq -0x60(%rbp), %rdi
movl -0x30(%rbp), %edx
movl 0x8(%r12), %esi
movl %edx, 0x28(%rbx)
cmpq $0x0, -0x58(%rbp)
movq %r14, -0x50(%rbp)
je 0x3b2de
testl %edx, %edx
jle 0x3b2ea
movq -0x38(%rbp), %rax
movswq 0x42(%rax), %rcx
testq %rcx, %rcx
setg -0x29(%rbp)
movl %edx, %eax
movq %rax, -0x70(%rbp)
movq $0x0, -0x40(%rbp)
leaq 0x3aefc(%rip), %r8      # 0x76060
movq %rsi, -0x78(%rbp)
testw %cx, %cx
jle 0x3b2ac
movq -0x38(%rbp), %rax
movq 0x8(%rax), %r9
movq -0x58(%rbp), %rax
movq 0x8(%rax), %rdx
movq -0x40(%rbp), %rdi
shlq $0x5, %rdi
movq 0x8(%rdx,%rdi), %rdi
xorl %r10d, %r10d
movb -0x29(%rbp), %r12b
leaq (%r10,%r10,2), %rdx
shlq $0x4, %rdx
movq (%r9,%rdx), %rdx
movb (%rdx), %r14b
testb %r14b, %r14b
je 0x3b1d1
incq %rdx
movq %rdi, %r11
movzbl %r14b, %eax
movb (%rax,%r8), %al
movzbl (%r11), %esi
cmpb (%rsi,%r8), %al
jne 0x3b1d4
incq %r11
movb (%rdx), %r14b
incq %rdx
testb %r14b, %r14b
jne 0x3b1af
jmp 0x3b1d4
movq %rdi, %r11
movzbl %r14b, %eax
movb (%rax,%r8), %al
movzbl (%r11), %edx
cmpb (%rdx,%r8), %al
je 0x3b1f7
incq %r10
cmpq %rcx, %r10
setl %r12b
jne 0x3b195
jmp 0x3b2ac
movq -0x40(%rbp), %rax
shlq $0x4, %rax
movq -0x60(%rbp), %rdx
movl %r10d, (%rdx,%rax)
testb $0x1, %r12b
je 0x3b2ac
movq -0x40(%rbp), %rdx
incq %rdx
movq %rdx, -0x40(%rbp)
cmpq -0x70(%rbp), %rdx
movq -0x50(%rbp), %r14
movl -0x30(%rbp), %edx
movq -0x78(%rbp), %rsi
jne 0x3b168
jmp 0x3b2ea
movzwl 0x42(%rdx), %eax
testw %ax, %ax
jle 0x3afea
movl $0x1, %ecx
testq %r14, %r14
je 0x3b037
cmpl $0x1, (%r14)
je 0x3b037
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
addq %rcx, %rax
movq 0x8(%rdx), %rcx
movl %eax, %eax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
movq (%rcx,%rax), %rdx
leaq 0x4043d(%rip), %rsi     # 0x7b6b9
xorl %ebx, %ebx
movq %r13, %rdi
movq %r12, %rcx
xorl %eax, %eax
callq 0x11724
jmp 0x3afec
xorl %ebx, %ebx
jmp 0x3b2d5
leaq 0x4045d(%rip), %rsi     # 0x7b6f8
xorl %ebx, %ebx
movq %r13, %rdi
xorl %eax, %eax
callq 0x11724
jmp 0x3afec
movq -0x58(%rbp), %rax
movq 0x8(%rax), %rax
movl -0x40(%rbp), %ecx
shlq $0x5, %rcx
movq 0x8(%rax,%rcx), %rdx
leaq 0x4048f(%rip), %rsi     # 0x7b756
movq %r13, %rdi
xorl %eax, %eax
callq 0x11724
movq -0x50(%rbp), %r14
movq -0x48(%rbp), %r15
jmp 0x3afec
movq -0x38(%rbp), %rax
movswl 0x42(%rax), %ecx
decl %ecx
movl %ecx, (%rdi)
testq %r14, %r14
setne %al
testl %edx, %edx
setg %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x3b36e
incl %esi
addq %rsi, %r15
movl %edx, %r13d
xorl %r14d, %r14d
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rax
movq %r14, %rcx
shlq $0x5, %rcx
movq 0x8(%rax,%rcx), %rsi
movl $0x0, %eax
testq %rsi, %rsi
movq -0x60(%rbp), %rdx
je 0x3b341
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %rsi, %rcx
incl %eax
cmpb $0x0, (%rcx)
leaq 0x1(%rcx), %rcx
jne 0x3b331
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
movq %r14, %rcx
shlq $0x4, %rcx
movq %r15, 0x8(%rdx,%rcx)
movl %eax, %r12d
movq %r15, %rdi
movq %r12, %rdx
callq 0x82f0
addq %r12, %r15
incq %r15
movb $0x0, -0x1(%r15)
incq %r14
cmpq %r13, %r14
jne 0x3b307
movb $0x0, 0x2c(%rbx)
movl -0x64(%rbp), %eax
movb %al, 0x2d(%rbx)
movb %ah, 0x2e(%rbx)
movq -0x38(%rbp), %rax
movq 0x68(%rax), %rdi
addq $0x50, %rdi
movq 0x10(%rbx), %rsi
testq %rsi, %rsi
je 0x3b3b3
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movq %rsi, %rax
movq -0x50(%rbp), %r14
movq -0x48(%rbp), %r15
incl %edx
cmpb $0x0, (%rax)
leaq 0x1(%rax), %rax
jne 0x3b3a0
andl $0x3fffffff, %edx       # imm = 0x3FFFFFFF
jmp 0x3b3bd
xorl %edx, %edx
movq -0x50(%rbp), %r14
movq -0x48(%rbp), %r15
movq %rbx, %rcx
callq 0x33cea
cmpq %rbx, %rax
je 0x3b3e4
testq %rax, %rax
je 0x3b3d7
movq %rax, 0x18(%rbx)
movq %rbx, 0x20(%rax)
movq -0x38(%rbp), %rax
movq %rbx, 0x20(%rax)
jmp 0x3afea
movb $0x1, 0x50(%r15)
jmp 0x3afec