// File: /workspace/github_c_makefile_star2_O1/barabo[P]advanced-shell-history/src/sqlite3.c
// Function: whereLoopAddBtree
static int whereLoopAddBtree(
  WhereLoopBuilder *pBuilder, /* WHERE clause information */
  Bitmask mExtra              /* Extra prerequesites for using this table */
){
  WhereInfo *pWInfo;          /* WHERE analysis context */
  Index *pProbe;              /* An index we are evaluating */
  Index sPk;                  /* A fake index object for the primary key */
  tRowcnt aiRowEstPk[2];      /* The aiRowEst[] value for the sPk index */
  int aiColumnPk = -1;        /* The aColumn[] value for the sPk index */
  SrcList *pTabList;          /* The FROM clause */
  struct SrcList_item *pSrc;  /* The FROM clause btree term to add */
  WhereLoop *pNew;            /* Template WhereLoop object */
  int rc = SQLITE_OK;         /* Return code */
  int iSortIdx = 1;           /* Index number */
  int b;                      /* A boolean value */
  WhereCost rSize;            /* number of rows in the table */
  WhereCost rLogSize;         /* Logarithm of the number of rows in the table */
  WhereClause *pWC;           /* The parsed WHERE clause */
  
  pNew = pBuilder->pNew;
  pWInfo = pBuilder->pWInfo;
  pTabList = pWInfo->pTabList;
  pSrc = pTabList->a + pNew->iTab;
  pWC = pBuilder->pWC;
  assert( !IsVirtual(pSrc->pTab) );

  if( pSrc->pIndex ){
    /* An INDEXED BY clause specifies a particular index to use */
    pProbe = pSrc->pIndex;
  }else{
    /* There is no INDEXED BY clause.  Create a fake Index object in local
    ** variable sPk to represent the rowid primary key index.  Make this
    ** fake index the first in a chain of Index objects with all of the real
    ** indices to follow */
    Index *pFirst;                  /* First of real indices on the table */
    memset(&sPk, 0, sizeof(Index));
    sPk.nColumn = 1;
    sPk.aiColumn = &aiColumnPk;
    sPk.aiRowEst = aiRowEstPk;
    sPk.onError = OE_Replace;
    sPk.pTable = pSrc->pTab;
    aiRowEstPk[0] = pSrc->pTab->nRowEst;
    aiRowEstPk[1] = 1;
    pFirst = pSrc->pTab->pIndex;
    if( pSrc->notIndexed==0 ){
      /* The real indices of the table are only considered if the
      ** NOT INDEXED qualifier is omitted from the FROM clause */
      sPk.pNext = pFirst;
    }
    pProbe = &sPk;
  }
  rSize = whereCost(pSrc->pTab->nRowEst);
  rLogSize = estLog(rSize);

#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
  /* Automatic indexes */
  if( !pBuilder->pOrSet
   && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
   && pSrc->pIndex==0
   && !pSrc->viaCoroutine
   && !pSrc->notIndexed
   && !pSrc->isCorrelated
  ){
    /* Generate auto-index WhereLoops */
    WhereTerm *pTerm;
    WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
    for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
      if( pTerm->prereqRight & pNew->maskSelf ) continue;
      if( termCanDriveIndex(pTerm, pSrc, 0) ){
        pNew->u.btree.nEq = 1;
        pNew->u.btree.pIndex = 0;
        pNew->nLTerm = 1;
        pNew->aLTerm[0] = pTerm;
        /* TUNING: One-time cost for computing the automatic index is
        ** approximately 7*N*log2(N) where N is the number of rows in
        ** the table being indexed. */
        pNew->rSetup = rLogSize + rSize + 28;  assert( 28==whereCost(7) );
        /* TUNING: Each index lookup yields 20 rows in the table.  This
        ** is more than the usual guess of 10 rows, since we have no way
        ** of knowning how selective the index will ultimately be.  It would
        ** not be unreasonable to make this value much larger. */
        pNew->nOut = 43;  assert( 43==whereCost(20) );
        pNew->rRun = whereCostAdd(rLogSize,pNew->nOut);
        pNew->wsFlags = WHERE_AUTO_INDEX;
        pNew->prereq = mExtra | pTerm->prereqRight;
        rc = whereLoopInsert(pBuilder, pNew);
      }
    }
  }
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */

  /* Loop over all indices
  */
  for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
    if( pProbe->pPartIdxWhere!=0
     && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){
      continue;  /* Partial index inappropriate for this query */
    }
    pNew->u.btree.nEq = 0;
    pNew->nLTerm = 0;
    pNew->iSortIdx = 0;
    pNew->rSetup = 0;
    pNew->prereq = mExtra;
    pNew->nOut = rSize;
    pNew->u.btree.pIndex = pProbe;
    b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
    /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
    assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 );
    if( pProbe->tnum<=0 ){
      /* Integer primary key index */
      pNew->wsFlags = WHERE_IPK;

      /* Full table scan */
      pNew->iSortIdx = b ? iSortIdx : 0;
      /* TUNING: Cost of full table scan is 3*(N + log2(N)).
      **  +  The extra 3 factor is to encourage the use of indexed lookups
      **     over full scans.  A smaller constant 2 is used for covering
      **     index scans so that a covering index scan will be favored over
      **     a table scan. */
      pNew->rRun = whereCostAdd(rSize,rLogSize) + 16;
      rc = whereLoopInsert(pBuilder, pNew);
      if( rc ) break;
    }else{
      Bitmask m = pSrc->colUsed & ~columnsInIndex(pProbe);
      pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;

      /* Full scan via index */
      if( b
       || ( m==0
         && pProbe->bUnordered==0
         && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
         && sqlite3GlobalConfig.bUseCis
         && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan)
          )
      ){
        pNew->iSortIdx = b ? iSortIdx : 0;
        if( m==0 ){
          /* TUNING: Cost of a covering index scan is 2*(N + log2(N)).
          **  +  The extra 2 factor is to encourage the use of indexed lookups
          **     over index scans.  A table scan uses a factor of 3 so that
          **     index scans are favored over table scans.
          **  +  If this covering index might also help satisfy the ORDER BY
          **     clause, then the cost is fudged down slightly so that this
          **     index is favored above other indices that have no hope of
          **     helping with the ORDER BY. */
          pNew->rRun = 10 + whereCostAdd(rSize,rLogSize) - b;
        }else{
          assert( b!=0 ); 
          /* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N)
          ** which we will simplify to just N*log2(N) */
          pNew->rRun = rSize + rLogSize;
        }
        rc = whereLoopInsert(pBuilder, pNew);
        if( rc ) break;
      }
    }
    rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);

    /* If there was an INDEXED BY clause, then only that one index is
    ** considered. */
    if( pSrc->pIndex ) break;
  }
  return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rsi, -0x88(%rbp)
movq %rdi, %r13
movl $0xffffffff, -0x74(%rbp) # imm = 0xFFFFFFFF
movq 0x18(%rdi), %r14
movq (%rdi), %rax
movq %rax, -0x58(%rbp)
movq 0x8(%rax), %rax
movzbl 0x10(%r14), %ecx
imulq $0x68, %rcx, %rcx
leaq (%rax,%rcx), %r15
addq $0x8, %r15
movq 0x60(%r15), %r12
testq %r12, %r12
jne 0x59c50
xorps %xmm0, %xmm0
leaq -0xf0(%rbp), %r12
movaps %xmm0, (%r12)
movaps %xmm0, 0x10(%r12)
movaps %xmm0, 0x40(%r12)
movaps %xmm0, 0x30(%r12)
movaps %xmm0, 0x20(%r12)
movq $0x0, 0x50(%r12)
movw $0x1, 0x54(%r12)
leaq -0x74(%rbp), %rax
movq %rax, 0x8(%r12)
leaq -0x90(%rbp), %rcx
movq %rcx, 0x10(%r12)
movb $0x5, 0x56(%r12)
movq 0x20(%r15), %rax
movq %rax, 0x18(%r12)
movl 0x38(%rax), %edx
movl %edx, (%rcx)
movl $0x1, 0x4(%rcx)
testb $0x1, 0x39(%r15)
jne 0x59c50
movq 0x10(%rax), %rax
movq %rax, -0xc8(%rbp)
movq 0x8(%r13), %rax
movq %rax, -0x68(%rbp)
movq 0x20(%r15), %rax
movl 0x38(%rax), %edi
callq 0x5a359
movq %rax, -0x70(%rbp)
movzwl %ax, %edi
movl %edi, -0x3c(%rbp)
callq 0x5a359
xorl %ebx, %ebx
subw $0x21, %ax
cmovbl %ebx, %eax
movq %rax, -0x48(%rbp)
cmpq $0x0, 0x20(%r13)
movq %r14, -0x50(%rbp)
movq %r15, -0x60(%rbp)
movq %r12, -0x38(%rbp)
jne 0x59cb5
movq -0x58(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
testb $0x10, 0x2e(%rax)
je 0x59cb5
cmpq $0x0, 0x60(%r15)
jne 0x59cb5
testb $0x7, 0x39(%r15)
je 0x59f9b
testl %ebx, %ebx
movq -0x38(%rbp), %r12
je 0x59cd1
movl %ebx, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq -0x70(%rbp), %rax
addl -0x48(%rbp), %eax
movl %eax, -0x30(%rbp)
movl $0x1, -0x2c(%rbp)
xorl %r8d, %r8d
movq %r13, -0x80(%rbp)
movq %r12, -0x38(%rbp)
movq 0x48(%r12), %r14
testq %r14, %r14
je 0x59d3b
movq -0x68(%rbp), %rcx
movl 0x14(%rcx), %r15d
xorl %ebx, %ebx
testl %r15d, %r15d
jle 0x59d32
movq -0x50(%rbp), %rax
movzbl 0x10(%rax), %r12d
movq 0x20(%rcx), %r13
movq (%r13), %rdi
movq %r14, %rsi
movl %r12d, %edx
callq 0x5aa52
xorl %r8d, %r8d
testl %eax, %eax
jne 0x59d3b
addq $0x38, %r13
decl %r15d
jne 0x59d13
movq -0x38(%rbp), %r12
jmp 0x59f76
movq -0x50(%rbp), %r14
movl $0x0, 0x18(%r14)
xorl %ebx, %ebx
movw %bx, 0x2c(%r14)
movb $0x0, 0x11(%r14)
movw %bx, 0x12(%r14)
movq -0x88(%rbp), %rax
movq %rax, (%r14)
movq -0x70(%rbp), %rax
movw %ax, 0x16(%r14)
movq -0x38(%rbp), %r12
movq %r12, 0x20(%r14)
testb $0x4, 0x57(%r12)
jne 0x59e2e
movq -0x80(%rbp), %r13
movq (%r13), %rax
movq 0x10(%rax), %rdx
testq %rdx, %rdx
movq -0x60(%rbp), %r15
je 0x59e3d
movslq (%rdx), %rax
testq %rax, %rax
jle 0x59e3d
movl 0x3c(%r15), %ecx
movq 0x8(%rdx), %rdx
xorl %esi, %esi
movq %rsi, %r8
shlq $0x5, %r8
movq (%rdx,%r8), %r8
testq %r8, %r8
je 0x59dd4
movzbl (%r8), %r9d
cmpl $0x5c, %r9d
je 0x59dce
cmpl $0x18, %r9d
jne 0x59dd4
movq 0x10(%r8), %r8
jmp 0x59db9
xorl %r9d, %r9d
cmpb $-0x68, (%r8)
movl $0x0, %ebx
jne 0x59e16
cmpl %ecx, 0x2c(%r8)
jne 0x59e11
movzwl 0x54(%r12), %r10d
testq %r10, %r10
je 0x59e11
movswl 0x30(%r8), %r8d
movq 0x8(%r12), %r11
xorl %ebx, %ebx
cmpl %r8d, (%r11,%rbx,4)
setne %r9b
je 0x59e27
incq %rbx
cmpq %rbx, %r10
jne 0x59dff
movb $0x1, %r9b
movl %edi, %ebx
testb %r9b, %r9b
je 0x59e3a
incq %rsi
movl %ebx, %edi
cmpq %rax, %rsi
jne 0x59dae
jmp 0x59e38
movl $0x1, %ebx
jmp 0x59e16
movq -0x80(%rbp), %r13
movq -0x60(%rbp), %r15
jmp 0x59e3d
xorl %ebx, %ebx
xorl %r8d, %r8d
cmpl $0x0, 0x50(%r12)
jle 0x59e7e
movzwl 0x54(%r12), %edx
testq %rdx, %rdx
je 0x59ebc
movq 0x8(%r12), %rsi
incq %rdx
xorl %eax, %eax
movl -0x8(%rsi,%rdx,4), %ecx
movl $0x1, %edi
shlq %cl, %rdi
cmpl $0x3f, %ecx
cmovgeq %r8, %rdi
orq %rdi, %rax
decq %rdx
cmpq $0x1, %rdx
jg 0x59e5a
notq %rax
jmp 0x59ec3
movl $0x100, 0x28(%r14)      # imm = 0x100
testl %ebx, %ebx
cmovnel -0x2c(%rbp), %ebx
movb %bl, 0x11(%r14)
movzwl -0x48(%rbp), %esi
movl -0x3c(%rbp), %edi
callq 0x5a551
addl $0x10, %eax
movw %ax, 0x14(%r14)
movq %r13, %rdi
movq %r14, %rsi
callq 0x5a153
testl %eax, %eax
je 0x59f56
jmp 0x59f94
movq $-0x1, %rax
xorl %ecx, %ecx
andq 0x50(%r15), %rax
sete %cl
orl $0x8, %ecx
shll $0x6, %ecx
movl %ecx, 0x28(%r14)
movl -0x2c(%rbp), %ecx
testl %ebx, %ebx
je 0x59eeb
movb %cl, 0x11(%r14)
testq %rax, %rax
je 0x59f1f
movl -0x30(%rbp), %eax
jmp 0x59f30
testq %rax, %rax
jne 0x59f4a
testb $0x4, 0x57(%r12)
jne 0x59f4a
movq -0x58(%rbp), %rcx
testb $0x4, 0x32(%rcx)
jne 0x59f4a
cmpl $0x0, 0x3a507(%rip)     # 0x94410
je 0x59f4a
movq -0x58(%rbp), %rcx
movq (%rcx), %rcx
movq (%rcx), %rdx
xorl %ecx, %ecx
testb $0x40, 0x4c(%rdx)
je 0x59edd
jmp 0x59f4a
movzwl -0x48(%rbp), %esi
movl -0x3c(%rbp), %edi
callq 0x5a551
subl %ebx, %eax
addl $0xa, %eax
movw %ax, 0x14(%r14)
movq %r13, %rdi
movq %r14, %rsi
callq 0x5a153
testl %eax, %eax
je 0x59f4a
movl %eax, %ebx
xorl %eax, %eax
jmp 0x59f4e
movb $0x1, %al
xorl %ebx, %ebx
testb %al, %al
je 0x59cbd
movq %r13, %rdi
movq %r15, %rsi
movq %r12, %rdx
xorl %ecx, %ecx
callq 0x5a5b1
xorl %r8d, %r8d
movl %eax, %ebx
cmpq $0x0, 0x60(%r15)
jne 0x59cbd
testl %ebx, %ebx
jne 0x59cbd
movq 0x28(%r12), %r12
incl -0x2c(%rbp)
testq %r12, %r12
jne 0x59ce9
jmp 0x59cbd
movl %eax, %ebx
jmp 0x59cbd
movq -0x68(%rbp), %rax
movslq 0x14(%rax), %rax
testq %rax, %rax
jle 0x59cb5
movq -0x68(%rbp), %rcx
movq 0x20(%rcx), %r12
imulq $0x38, %rax, %r15
addq %r12, %r15
movq -0x70(%rbp), %rax
movq -0x48(%rbp), %rcx
addl %ecx, %eax
addl $0x1c, %eax
movl %eax, -0x2c(%rbp)
addq $0x38, %r12
movzwl %cx, %eax
movl %eax, -0x30(%rbp)
movq 0x8(%r14), %rax
xorl %ebx, %ebx
testq %rax, -0x10(%r12)
jne 0x5a05c
leaq -0x38(%r12), %r14
xorl %ebx, %ebx
movq %r14, %rdi
movq -0x60(%rbp), %rsi
xorl %edx, %edx
callq 0x5a4e7
testl %eax, %eax
je 0x5a05c
movq -0x50(%rbp), %rbx
movl $0x1, 0x18(%rbx)
movq $0x0, 0x20(%rbx)
movw $0x1, 0x2c(%rbx)
movq 0x30(%rbx), %rax
movq %r14, (%rax)
movl -0x2c(%rbp), %eax
movw %ax, 0x12(%rbx)
movw $0x2b, 0x16(%rbx)
movl -0x30(%rbp), %edi
movl $0x2b, %esi
callq 0x5a551
movw %ax, 0x14(%rbx)
movl $0x4000, 0x28(%rbx)     # imm = 0x4000
movq -0x10(%r12), %rax
orq -0x88(%rbp), %rax
movq %rax, (%rbx)
movq %r13, %rdi
movq %rbx, %rsi
callq 0x5a153
movl %eax, %ebx
testl %ebx, %ebx
jne 0x59cb5
leaq 0x38(%r12), %rax
cmpq %r15, %r12
movq %rax, %r12
movq -0x50(%rbp), %r14
jb 0x59fd5
jmp 0x59cb5