// File: /workspace/github_c_makefile_star2_O2/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 $0x68, %rsp
movq %rcx, %r15
movq %rsi, %rbx
movl %r8d, -0x64(%rbp)
movq (%rdi), %r12
movq 0x238(%rdi), %r14
testq %r14, %r14
je 0x37818
cmpb $0x0, 0x201(%rdi)
je 0x37846
xorl %esi, %esi
movq %r12, %rdi
callq 0x968b
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2f527
movq %r12, %rdi
movq %r15, %rsi
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2f527
movq %rdx, %r9
testq %rbx, %rbx
je 0x3786a
movl (%rbx), %ecx
testq %r15, %r15
je 0x37886
cmpl %ecx, (%r15)
je 0x37886
leaq 0x35eb7(%rip), %rsi     # 0x6d718
xorl %eax, %eax
callq 0x104d6
jmp 0x37818
movzwl 0x42(%r14), %eax
testw %ax, %ax
jle 0x37818
pushq $0x1
popq %rcx
testq %r15, %r15
je 0x37886
cmpl $0x1, (%r15)
jne 0x37b24
movq %rdi, -0x88(%rbp)
movq %rcx, -0x58(%rbp)
movl %ecx, %eax
shll $0x4, %eax
movq %r9, -0x30(%rbp)
movl 0x8(%r9), %ecx
leal (%rax,%rcx), %r13d
addl $0x41, %r13d
testq %r15, %r15
movq %rbx, -0x40(%rbp)
movq %r14, -0x48(%rbp)
je 0x378ea
movl (%r15), %r14d
xorl %ebx, %ebx
testl %r14d, %r14d
cmovlel %ebx, %r14d
shlq $0x5, %r14
cmpq %rbx, %r14
je 0x378e2
movq 0x8(%r15), %rax
movq 0x8(%rax,%rbx), %rdi
callq 0x8f8e
addl %eax, %r13d
incl %r13d
addq $0x20, %rbx
jmp 0x378c3
movq -0x40(%rbp), %rbx
movq -0x48(%rbp), %r14
movq %r12, %rdi
movl %r13d, %esi
callq 0xf4ae
testq %rax, %rax
je 0x37818
movq %r14, (%rax)
movq %rax, %rcx
movq %rax, -0x38(%rbp)
movq 0x20(%r14), %rax
movq %rax, 0x8(%rcx)
leaq 0x40(%rcx), %rax
movq %rax, -0x70(%rbp)
movslq -0x58(%rbp), %rax
shlq $0x4, %rax
leaq (%rcx,%rax), %r13
addq $0x40, %r13
movq %r13, 0x10(%rcx)
movq -0x30(%rbp), %rax
movq (%rax), %rsi
movl 0x8(%rax), %edx
movq %r13, %rdi
callq 0x82c0
movq -0x30(%rbp), %rax
movl 0x8(%rax), %eax
movb $0x0, (%rax,%r13)
movq %r13, -0x60(%rbp)
movq %r13, %rdi
callq 0x4221d
movq -0x58(%rbp), %rsi
movq -0x30(%rbp), %rax
movl 0x8(%rax), %eax
movq %rax, -0x80(%rbp)
movq -0x38(%rbp), %rax
movl %esi, 0x28(%rax)
testq %rbx, %rbx
movq %r15, -0x30(%rbp)
movq %r12, -0x50(%rbp)
je 0x37a45
testl %esi, %esi
movl $0x0, %ecx
cmovgl %esi, %ecx
xorl %r13d, %r13d
movq %rsi, %rbx
movq %rcx, -0x78(%rbp)
cmpq %rcx, %r13
je 0x37a55
movzwl 0x42(%r14), %eax
testw %ax, %ax
movl $0x0, %ecx
cmovlel %ecx, %eax
movzwl %ax, %r14d
movq %r13, %rbx
shlq $0x5, %rbx
xorl %r12d, %r12d
xorl %r15d, %r15d
cmpq %r15, %r14
je 0x37a0f
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax,%r12), %rdi
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax,%rbx), %rsi
callq 0xb1bf
testl %eax, %eax
je 0x379eb
incq %r15
addq $0x30, %r12
jmp 0x379bb
movq %r13, %rax
shlq $0x4, %rax
movq -0x70(%rbp), %rcx
movl %r15d, (%rcx,%rax)
incq %r13
movq -0x30(%rbp), %r15
movq -0x48(%rbp), %r14
movq -0x58(%rbp), %rbx
movq -0x78(%rbp), %rcx
jmp 0x37991
movq -0x40(%rbp), %rbx
movq 0x8(%rbx), %rax
movl %r13d, %ecx
shlq $0x5, %rcx
movq 0x8(%rax,%rcx), %rdx
leaq 0x35d4c(%rip), %rsi     # 0x6d776
movq -0x88(%rbp), %rdi
xorl %eax, %eax
callq 0x104d6
movq -0x30(%rbp), %r15
movq -0x50(%rbp), %r12
jmp 0x37b62
movswl 0x42(%r14), %eax
decl %eax
movq -0x70(%rbp), %rcx
movl %eax, (%rcx)
movq %rsi, %rbx
testq %r15, %r15
je 0x37abe
movq -0x80(%rbp), %rax
incl %eax
addq %rax, -0x60(%rbp)
xorl %r14d, %r14d
testl %ebx, %ebx
cmovlel %r14d, %ebx
shlq $0x4, %rbx
cmpq %r14, %rbx
je 0x37abe
movq 0x8(%r15), %rax
movq 0x8(%rax,%r14,2), %r12
movq %r12, %rdi
callq 0x8f8e
movq -0x38(%rbp), %rcx
movq -0x60(%rbp), %r13
movq %r13, 0x48(%rcx,%r14)
movl %eax, %r15d
movq %r13, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x82c0
addq %r15, %r13
incq %r13
movq -0x30(%rbp), %r15
movq %r13, -0x60(%rbp)
movb $0x0, -0x1(%r13)
addq $0x10, %r14
jmp 0x37a71
movq -0x38(%rbp), %rbx
movb $0x0, 0x2c(%rbx)
movl -0x64(%rbp), %eax
movb %al, 0x2d(%rbx)
movb %ah, 0x2e(%rbx)
movq -0x48(%rbp), %r14
movq 0x68(%r14), %r15
addq $0x50, %r15
movq 0x10(%rbx), %r12
movq %r12, %rdi
callq 0x8f8e
movq %r15, %rdi
movq %r12, %rsi
movl %eax, %edx
movq %rbx, %rcx
callq 0x2f1a7
cmpq %rbx, %rax
je 0x37b50
testq %rax, %rax
movq -0x50(%rbp), %r12
movq -0x38(%rbp), %rcx
je 0x37b11
movq %rax, 0x18(%rcx)
movq %rcx, 0x20(%rax)
movq %rcx, 0x20(%r14)
xorl %esi, %esi
movq -0x30(%rbp), %r15
movq -0x40(%rbp), %rbx
jmp 0x3781a
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
addq %rcx, %rax
movq 0x8(%r14), %rcx
movl %eax, %eax
imulq $0x30, %rax, %rax
movq (%rcx,%rax), %rdx
leaq 0x35b98(%rip), %rsi     # 0x6d6d9
movq %r9, %rcx
xorl %eax, %eax
callq 0x104d6
jmp 0x37818
movq -0x50(%rbp), %r12
movb $0x1, 0x50(%r12)
movq -0x30(%rbp), %r15
movq -0x40(%rbp), %rbx
movq -0x38(%rbp), %rsi
jmp 0x3781a