// File: /workspace/github_c_makefile_star2_O3/genometools[P]genometools/src/external/sqlite-3.33.0/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 *pRightTab = pRight->pTab;
    int isOuter;

    if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
    isOuter = (pRight->fg.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->fg.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 */

        if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue;
        zName = pRightTab->aCol[j].zName;
        if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 1) ){
          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 ) sqlite3SetJoinExpr(pRight->pOn, pRight->iCursor);
      p->pWhere = sqlite3ExprAnd(pParse, 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, 0)
        ){
          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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rdi, (%rsp)
movq 0x28(%rsi), %r8
cmpl $0x2, (%r8)
jl 0x2c8abf
leaq 0x8(%r8), %rdx
leaq 0x78(%r8), %r14
addq $0x30, %rsi
movq %rsi, 0x8(%rsp)
leaq 0x28(%r8), %rax
movq %rax, 0x50(%rsp)
xorl %esi, %esi
movq %r8, 0x10(%rsp)
movq 0x20(%r14), %rbp
cmpq $0x0, 0x20(%rdx)
sete %al
testq %rbp, %rbp
sete %cl
orb %al, %cl
jne 0x2c8aa5
movq %rsi, 0x18(%rsp)
movq %rdx, 0x30(%rsp)
movzbl 0x3c(%r14), %eax
movl %eax, %ebx
andl $0x20, %ebx
movl %ebx, %ecx
shrl $0x5, %ecx
movq %rcx, 0x38(%rsp)
testb $0x4, %al
je 0x2c8988
cmpq $0x0, 0x48(%r14)
jne 0x2c8aec
cmpq $0x0, 0x50(%r14)
jne 0x2c8aec
cmpw $0x0, 0x46(%rbp)
jle 0x2c8988
movq 0x18(%rsp), %rax
leal 0x1(%rax), %r12d
xorl %r15d, %r15d
xorl %r13d, %r13d
movq 0x8(%rbp), %rax
testb $0x2, 0x1c(%rax,%r15)
jne 0x2c8977
movq (%rax,%r15), %rdx
movq %r8, %rdi
movl %r12d, %esi
leaq 0x2c(%rsp), %rcx
leaq 0x28(%rsp), %r8
movl $0x1, %r9d
callq 0x2c8b16
movq 0x10(%rsp), %r8
testl %eax, %eax
je 0x2c8977
movl 0x2c(%rsp), %edx
movl 0x28(%rsp), %ecx
movq (%rsp), %rdi
movq %r8, %rsi
movl %r12d, %r8d
movl %r13d, %r9d
pushq 0x8(%rsp)
pushq 0x40(%rsp)
callq 0x2c9264
movq 0x20(%rsp), %r8
addq $0x10, %rsp
incq %r13
movswq 0x46(%rbp), %rax
addq $0x20, %r15
cmpq %rax, %r13
jl 0x2c8918
movq 0x48(%r14), %rdx
testq %rdx, %rdx
je 0x2c89d1
cmpq $0x0, 0x50(%r14)
jne 0x2c8b02
testl %ebx, %ebx
je 0x2c89b0
movl 0x40(%r14), %esi
movq %rdx, %rdi
callq 0x2c92f3
movq 0x48(%r14), %rdx
movq 0x8(%rsp), %rbx
movq (%rbx), %rsi
movq (%rsp), %rdi
callq 0x2b6b0e
movq %rax, (%rbx)
movq $0x0, 0x48(%r14)
movq 0x10(%rsp), %r8
movq 0x50(%r14), %rcx
testq %rcx, %rcx
movq 0x30(%rsp), %rdx
movq 0x18(%rsp), %rsi
je 0x2c8aa5
cmpl $0x0, 0x8(%rcx)
jle 0x2c8aa5
leal 0x1(%rsi), %eax
movl %eax, 0x20(%rsp)
leaq 0x1(%rsi), %r15
xorl %edi, %edi
movq %rcx, 0x40(%rsp)
movq (%rcx), %rax
movq %rdi, 0x48(%rsp)
movq %rdi, %rcx
shlq $0x4, %rcx
movq (%rax,%rcx), %r12
movq %rbp, %rdi
movq %r12, %rsi
callq 0x2c936a
movl %eax, 0x24(%rsp)
testl %eax, %eax
js 0x2c8ac3
movq 0x50(%rsp), %r13
xorl %ebx, %ebx
movq (%r13), %rdi
movq %r12, %rsi
callq 0x2c936a
testl %eax, %eax
jns 0x2c8a53
incq %rbx
addq $0x70, %r13
cmpq %rbx, %r15
jne 0x2c8a35
jmp 0x2c8ac3
movq (%rsp), %rdi
movq 0x10(%rsp), %r12
movq %r12, %rsi
movl %ebx, %edx
movl %eax, %ecx
movl 0x20(%rsp), %r8d
movl 0x24(%rsp), %r9d
pushq 0x8(%rsp)
pushq 0x40(%rsp)
callq 0x2c9264
movq %r12, %r8
addq $0x10, %rsp
movq 0x48(%rsp), %rdi
incq %rdi
movq 0x40(%rsp), %rcx
movslq 0x8(%rcx), %rax
cmpq %rax, %rdi
movq 0x30(%rsp), %rdx
movq 0x18(%rsp), %rsi
jl 0x2c8a04
incq %rsi
addq $0x70, %r14
addq $0x70, %rdx
movslq (%r8), %rax
decq %rax
cmpq %rax, %rsi
jl 0x2c88ac
xorl %eax, %eax
jmp 0x2c8add
leaq 0x10f449(%rip), %rsi    # 0x3d7f13
movq (%rsp), %rdi
movq %r12, %rdx
xorl %eax, %eax
callq 0x27b48d
movl $0x1, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x10f3b7(%rip), %rsi    # 0x3d7eaa
movq (%rsp), %rdi
xorl %edx, %edx
xorl %eax, %eax
callq 0x27b48d
jmp 0x2c8ad8
leaq 0x10f3d3(%rip), %rsi    # 0x3d7edc
movq (%rsp), %rdi
xorl %eax, %eax
callq 0x27b48d
jmp 0x2c8ad8