// File: /workspace/github_c_makefile_star2_O3/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, %r12
movq %rdx, %r15
movq (%rdi), %r14
movq 0x238(%rdi), %rdx
testq %rdx, %rdx
movq %rsi, -0x58(%rbp)
je 0x3b621
movq %rdi, %r13
cmpb $0x0, 0x201(%rdi)
je 0x3b653
xorl %ebx, %ebx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x9ca4
movq %r14, %rdi
movq -0x58(%rbp), %rsi
callq 0x3484e
movq %r14, %rdi
movq %r12, %rsi
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3484e
testq %rsi, %rsi
movq %rdx, -0x48(%rbp)
je 0x3b691
movl (%rsi), %edi
testq %r12, %r12
je 0x3b718
movl (%r12), %ecx
cmpl %edi, %ecx
jne 0x3b736
movq %r12, -0x30(%rbp)
movl %edi, %eax
shll $0x4, %eax
movl 0x8(%r15), %edx
leal (%rax,%rdx), %r12d
addl $0x41, %r12d
testl %ecx, %ecx
movl %edi, -0x40(%rbp)
jg 0x3b6c6
jmp 0x3b70d
movzwl 0x42(%rdx), %eax
testw %ax, %ax
jle 0x3b621
testq %r12, %r12
je 0x3b74e
cmpl $0x1, (%r12)
jne 0x3ba0a
movq %r12, -0x30(%rbp)
movl 0x8(%r15), %r12d
addl $0x51, %r12d
movl $0x1, -0x40(%rbp)
movl $0x1, %ecx
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movl %ecx, %ecx
xorl %edx, %edx
movq %rdx, %rsi
shlq $0x5, %rsi
movq 0x8(%rax,%rsi), %rdi
testq %rdi, %rdi
je 0x3b6fd
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
incl %esi
cmpb $0x0, (%rdi)
leaq 0x1(%rdi), %rdi
jne 0x3b6e8
andl $0x3fffffff, %esi       # imm = 0x3FFFFFFF
incl %esi
jmp 0x3b702
movl $0x1, %esi
addl %esi, %r12d
incq %rdx
cmpq %rcx, %rdx
jne 0x3b6d2
movl %r8d, -0x38(%rbp)
movb $0x1, %al
movl %eax, -0x34(%rbp)
jmp 0x3b76c
movl %r8d, -0x38(%rbp)
movq %r12, -0x30(%rbp)
movl %edi, -0x40(%rbp)
movl %edi, %eax
shll $0x4, %eax
movl 0x8(%r15), %ecx
leal (%rax,%rcx), %r12d
addl $0x41, %r12d
jmp 0x3b765
leaq 0x3ffbb(%rip), %rsi     # 0x7b6f8
xorl %ebx, %ebx
movq %r13, %rdi
xorl %eax, %eax
callq 0x11842
jmp 0x3b623
movl %r8d, -0x38(%rbp)
movq %r12, -0x30(%rbp)
movl 0x8(%r15), %r12d
addl $0x51, %r12d
movl $0x1, -0x40(%rbp)
movl $0x0, -0x34(%rbp)
movq %r14, %rdi
movl %r12d, %esi
callq 0x11721
testq %rax, %rax
je 0x3b8cc
movq %rax, %rbx
movslq %r12d, %rdx
movq %rax, %rdi
xorl %esi, %esi
callq 0x8200
movq -0x48(%rbp), %rax
movq %rax, (%rbx)
movq 0x20(%rax), %rax
movq %rax, 0x8(%rbx)
leaq 0x40(%rbx), %rax
movq %rax, -0x60(%rbp)
movslq -0x40(%rbp), %rax
movq %rax, -0x50(%rbp)
shlq $0x4, %rax
leaq (%rbx,%rax), %r12
addq $0x40, %r12
movq %r12, 0x10(%rbx)
movq (%r15), %rsi
movl 0x8(%r15), %edx
movq %r12, %rdi
callq 0x82f0
movl 0x8(%r15), %eax
movb $0x0, (%rax,%r12)
movq %r12, %rdi
callq 0x461c6
movq -0x60(%rbp), %rcx
movl 0x8(%r15), %esi
movq -0x50(%rbp), %rax
movl %eax, 0x28(%rbx)
cmpq $0x0, -0x58(%rbp)
je 0x3b8d3
movl -0x40(%rbp), %edx
testl %edx, %edx
jle 0x3b968
movq -0x48(%rbp), %rax
movswq 0x42(%rax), %rcx
movl %edx, %edx
movq %rdx, -0x68(%rbp)
xorl %r8d, %r8d
leaq 0x3a893(%rip), %rdi     # 0x760b0
movq %rsi, -0x70(%rbp)
testw %cx, %cx
jle 0x3ba3f
movq 0x8(%rax), %r9
movq -0x58(%rbp), %rax
movq 0x8(%rax), %rdx
movq %r8, -0x50(%rbp)
movq %r8, %rax
shlq $0x5, %rax
movq %rdx, -0x78(%rbp)
movq 0x8(%rdx,%rax), %r11
xorl %r10d, %r10d
leaq (%r10,%r10,2), %rax
shlq $0x4, %rax
movq (%r9,%rax), %rsi
movb (%rsi), %al
testb %al, %al
je 0x3b884
incq %rsi
movq %r11, %r15
movzbl %al, %eax
movb (%rax,%rdi), %r8b
movzbl (%r15), %edx
cmpb (%rdx,%rdi), %r8b
jne 0x3b889
incq %r15
movb (%rsi), %al
incq %rsi
testb %al, %al
jne 0x3b865
jmp 0x3b887
movq %r11, %r15
xorl %eax, %eax
movb (%rax,%rdi), %al
movzbl (%r15), %edx
cmpb (%rdx,%rdi), %al
je 0x3b8a2
incq %r10
cmpq %rcx, %r10
jne 0x3b84d
jmp 0x3b9a9
movq -0x50(%rbp), %r8
movq %r8, %rax
shlq $0x4, %rax
movq -0x60(%rbp), %rdx
movl %r10d, (%rdx,%rax)
incq %r8
cmpq -0x68(%rbp), %r8
movq -0x48(%rbp), %rax
movq -0x70(%rbp), %rsi
jne 0x3b821
jmp 0x3b8df
xorl %ebx, %ebx
jmp 0x3b9ca
movq -0x48(%rbp), %rax
movswl 0x42(%rax), %eax
decl %eax
movl %eax, (%rcx)
movl -0x40(%rbp), %ecx
testl %ecx, %ecx
setg %al
movl -0x34(%rbp), %edx
andb %al, %dl
cmpb $0x1, %dl
jne 0x3b968
incl %esi
addq %rsi, %r12
movl %ecx, %eax
movq %rax, -0x40(%rbp)
xorl %r13d, %r13d
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %r13, %rcx
shlq $0x5, %rcx
movq 0x8(%rax,%rcx), %rsi
movl $0x0, %eax
testq %rsi, %rsi
movq -0x60(%rbp), %rdx
je 0x3b939
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %rsi, %rcx
incl %eax
cmpb $0x0, (%rcx)
leaq 0x1(%rcx), %rcx
jne 0x3b929
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
movq %r13, %rcx
shlq $0x4, %rcx
movq %r12, 0x8(%rdx,%rcx)
movl %eax, %r15d
movq %r12, %rdi
movq %r15, %rdx
callq 0x82f0
addq %r15, %r12
incq %r12
movb $0x0, -0x1(%r12)
incq %r13
cmpq -0x40(%rbp), %r13
jne 0x3b8ff
movb $0x0, 0x2c(%rbx)
movl -0x38(%rbp), %eax
movb %al, 0x2d(%rbx)
movb %ah, 0x2e(%rbx)
movq -0x48(%rbp), %rax
movq 0x68(%rax), %rdi
addq $0x50, %rdi
movq 0x10(%rbx), %rsi
testq %rsi, %rsi
je 0x3b9d3
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movq %rsi, %rax
movq -0x30(%rbp), %r12
incl %edx
cmpb $0x0, (%rax)
leaq 0x1(%rax), %rax
jne 0x3b996
andl $0x3fffffff, %edx       # imm = 0x3FFFFFFF
jmp 0x3b9d9
movl -0x50(%rbp), %eax
movq -0x78(%rbp), %rcx
shlq $0x5, %rax
movq 0x8(%rcx,%rax), %rdx
leaq 0x3fd96(%rip), %rsi     # 0x7b756
movq %r13, %rdi
xorl %eax, %eax
callq 0x11842
movq -0x30(%rbp), %r12
jmp 0x3b623
xorl %edx, %edx
movq -0x30(%rbp), %r12
movq %rbx, %rcx
callq 0x34400
cmpq %rbx, %rax
je 0x3ba00
testq %rax, %rax
je 0x3b9f3
movq %rax, 0x18(%rbx)
movq %rbx, 0x20(%rax)
movq -0x48(%rbp), %rax
movq %rbx, 0x20(%rax)
jmp 0x3b621
movb $0x1, 0x50(%r14)
jmp 0x3b623
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 0x3fc8e(%rip), %rsi     # 0x7b6b9
xorl %ebx, %ebx
movq %r13, %rdi
movq %r15, %rcx
xorl %eax, %eax
callq 0x11842
jmp 0x3b623
movq -0x58(%rbp), %rax
movq 0x8(%rax), %rcx
xorl %eax, %eax
jmp 0x3b9b0