// File: /workspace/github_c_makefile_star2_O0/barabo[P]advanced-shell-history/src/sqlite3.c
// Function: sqliteProcessJoin
static int sqliteProcessJoin(Parse *pParse, Select *p){
  SrcList *pSrc;                  /* All tables in the FROM clause */
  int i, j;                       /* Loop counters */
  struct SrcList_item *pLeft;     /* Left table being joined */
  struct SrcList_item *pRight;    /* Right table being joined */

  pSrc = p->pSrc;
  pLeft = &pSrc->a[0];
  pRight = &pLeft[1];
  for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
    Table *pLeftTab = pLeft->pTab;
    Table *pRightTab = pRight->pTab;
    int isOuter;

    if( NEVER(pLeftTab==0 || pRightTab==0) ) continue;
    isOuter = (pRight->jointype & JT_OUTER)!=0;

    /* When the NATURAL keyword is present, add WHERE clause terms for
    ** every column that the two tables have in common.
    */
    if( pRight->jointype & JT_NATURAL ){
      if( pRight->pOn || pRight->pUsing ){
        sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
           "an ON or USING clause", 0);
        return 1;
      }
      for(j=0; j<pRightTab->nCol; j++){
        char *zName;   /* Name of column in the right table */
        int iLeft;     /* Matching left table */
        int iLeftCol;  /* Matching column in the left table */

        zName = pRightTab->aCol[j].zName;
        if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) ){
          addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j,
                       isOuter, &p->pWhere);
        }
      }
    }

    /* Disallow both ON and USING clauses in the same join
    */
    if( pRight->pOn && pRight->pUsing ){
      sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
        "clauses in the same join");
      return 1;
    }

    /* Add the ON clause to the end of the WHERE clause, connected by
    ** an AND operator.
    */
    if( pRight->pOn ){
      if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor);
      p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn);
      pRight->pOn = 0;
    }

    /* Create extra terms on the WHERE clause for each column named
    ** in the USING clause.  Example: If the two tables to be joined are 
    ** A and B and the USING clause names X, Y, and Z, then add this
    ** to the WHERE clause:    A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
    ** Report an error if any column mentioned in the USING clause is
    ** not contained in both tables to be joined.
    */
    if( pRight->pUsing ){
      IdList *pList = pRight->pUsing;
      for(j=0; j<pList->nId; j++){
        char *zName;     /* Name of the term in the USING clause */
        int iLeft;       /* Table on the left with matching column name */
        int iLeftCol;    /* Column number of matching column on the left */
        int iRightCol;   /* Column number of matching column on the right */

        zName = pList->a[j].zName;
        iRightCol = columnIndex(pRightTab, zName);
        if( iRightCol<0
         || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol)
        ){
          sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
            "not present in both tables", zName);
          return 1;
        }
        addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol,
                     isOuter, &p->pWhere);
      }
    }
  }
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
addq $0x68, %rax
movq %rax, -0x38(%rbp)
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
movq -0x20(%rbp), %rcx
movzbl (%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x6476f
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x644d9
cmpq $0x0, -0x48(%rbp)
jne 0x644de
jmp 0x64749
movq -0x38(%rbp), %rax
movzbl 0x38(%rax), %eax
andl $0x20, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x4c(%rbp)
movq -0x38(%rbp), %rax
movzbl 0x38(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x645d7
movq -0x38(%rbp), %rax
cmpq $0x0, 0x40(%rax)
jne 0x64521
movq -0x38(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0x64541
movq -0x10(%rbp), %rdi
leaq 0x4b797(%rip), %rsi     # 0xafcc3
xorl %edx, %edx
movb $0x0, %al
callq 0x136f0
movl $0x1, -0x4(%rbp)
jmp 0x64776
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
movq -0x48(%rbp), %rcx
movswl 0x42(%rcx), %ecx
cmpl %ecx, %eax
jge 0x645d5
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x28(%rbp), %rcx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x20(%rbp), %rdi
movl -0x24(%rbp), %esi
addl $0x1, %esi
movq -0x58(%rbp), %rdx
leaq -0x5c(%rbp), %rcx
leaq -0x60(%rbp), %r8
callq 0x64790
cmpl $0x0, %eax
je 0x645c5
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
movl -0x5c(%rbp), %edx
movl -0x60(%rbp), %ecx
movl -0x24(%rbp), %r8d
addl $0x1, %r8d
movl -0x28(%rbp), %r9d
movl -0x4c(%rbp), %r10d
movq -0x18(%rbp), %rax
addq $0x30, %rax
movl %r10d, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x64a40
jmp 0x645c7
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x64548
jmp 0x645d7
movq -0x38(%rbp), %rax
cmpq $0x0, 0x40(%rax)
je 0x6460b
movq -0x38(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0x6460b
movq -0x10(%rbp), %rdi
leaq 0x4b6fd(%rip), %rsi     # 0xafcf5
movb $0x0, %al
callq 0x136f0
movl $0x1, -0x4(%rbp)
jmp 0x64776
movq -0x38(%rbp), %rax
cmpq $0x0, 0x40(%rax)
je 0x64663
cmpl $0x0, -0x4c(%rbp)
je 0x64630
movq -0x38(%rbp), %rax
movq 0x40(%rax), %rdi
movq -0x38(%rbp), %rax
movl 0x3c(%rax), %esi
callq 0x64b10
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rsi
movq -0x38(%rbp), %rax
movq 0x40(%rax), %rdx
callq 0x64b70
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x40(%rax)
movq -0x38(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0x64747
movq -0x38(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0x68(%rbp)
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
movq -0x68(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jge 0x64745
movq -0x68(%rbp), %rax
movq (%rax), %rax
movslq -0x28(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
movq %rax, -0x70(%rbp)
movq -0x48(%rbp), %rdi
movq -0x70(%rbp), %rsi
callq 0x64c40
movl %eax, -0x7c(%rbp)
cmpl $0x0, -0x7c(%rbp)
jl 0x646e4
movq -0x20(%rbp), %rdi
movl -0x24(%rbp), %esi
addl $0x1, %esi
movq -0x70(%rbp), %rdx
leaq -0x74(%rbp), %rcx
leaq -0x78(%rbp), %r8
callq 0x64790
cmpl $0x0, %eax
jne 0x64703
movq -0x10(%rbp), %rdi
movq -0x70(%rbp), %rdx
leaq 0x4b639(%rip), %rsi     # 0xafd2c
movb $0x0, %al
callq 0x136f0
movl $0x1, -0x4(%rbp)
jmp 0x64776
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
movl -0x74(%rbp), %edx
movl -0x78(%rbp), %ecx
movl -0x24(%rbp), %r8d
addl $0x1, %r8d
movl -0x7c(%rbp), %r9d
movl -0x4c(%rbp), %r10d
movq -0x18(%rbp), %rax
addq $0x30, %rax
movl %r10d, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x64a40
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x64685
jmp 0x64747
jmp 0x64749
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
movq -0x38(%rbp), %rax
addq $0x68, %rax
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
addq $0x68, %rax
movq %rax, -0x30(%rbp)
jmp 0x6449e
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)