// File: /workspace/github_c_makefile_star2_O1/barabo[P]advanced-shell-history/src/sqlite3.c
// Function: sqlite3CodeSubselect
SQLITE_PRIVATE int sqlite3CodeSubselect(
  Parse *pParse,          /* Parsing context */
  Expr *pExpr,            /* The IN, SELECT, or EXISTS operator */
  int rMayHaveNull,       /* Register that records whether NULLs exist in RHS */
  int isRowid             /* If true, LHS of IN operator is a rowid */
){
  int testAddr = -1;                      /* One-time test address */
  int rReg = 0;                           /* Register storing resulting */
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( NEVER(v==0) ) return 0;
  sqlite3ExprCachePush(pParse);

  /* This code must be run in its entirety every time it is encountered
  ** if any of the following is true:
  **
  **    *  The right-hand side is a correlated subquery
  **    *  The right-hand side is an expression list containing variables
  **    *  We are inside a trigger
  **
  ** If all of the above are false, then we can run this code just once
  ** save the results, and reuse the same result on subsequent invocations.
  */
  if( !ExprHasAnyProperty(pExpr, EP_VarSelect) ){
    testAddr = sqlite3CodeOnce(pParse);
  }

#ifndef SQLITE_OMIT_EXPLAIN
  if( pParse->explain==2 ){
    char *zMsg = sqlite3MPrintf(
        pParse->db, "EXECUTE %s%s SUBQUERY %d", testAddr>=0?"":"CORRELATED ",
        pExpr->op==TK_IN?"LIST":"SCALAR", pParse->iNextSelectId
    );
    sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
  }
#endif

  switch( pExpr->op ){
    case TK_IN: {
      char affinity;              /* Affinity of the LHS of the IN */
      int addr;                   /* Address of OP_OpenEphemeral instruction */
      Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
      KeyInfo *pKeyInfo = 0;      /* Key information */

      if( rMayHaveNull ){
        sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
      }

      affinity = sqlite3ExprAffinity(pLeft);

      /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
      ** expression it is handled the same way.  An ephemeral table is 
      ** filled with single-field index keys representing the results
      ** from the SELECT or the <exprlist>.
      **
      ** If the 'x' expression is a column value, or the SELECT...
      ** statement returns a column value, then the affinity of that
      ** column is used to build the index keys. If both 'x' and the
      ** SELECT... statement are columns, then numeric affinity is used
      ** if either column has NUMERIC or INTEGER affinity. If neither
      ** 'x' nor the SELECT... statement are columns, then numeric affinity
      ** is used.
      */
      pExpr->iTable = pParse->nTab++;
      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
      if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
      pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1);

      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        /* Case 1:     expr IN (SELECT ...)
        **
        ** Generate code to write the results of the select into the temporary
        ** table allocated and opened above.
        */
        SelectDest dest;
        ExprList *pEList;

        assert( !isRowid );
        sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
        dest.affSdst = (u8)affinity;
        assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
        pExpr->x.pSelect->iLimit = 0;
        testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
        if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
          sqlite3DbFree(pParse->db, pKeyInfo);
          return 0;
        }
        pEList = pExpr->x.pSelect->pEList;
        assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
        assert( pEList!=0 );
        assert( pEList->nExpr>0 );
        pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
                                                         pEList->a[0].pExpr);
      }else if( ALWAYS(pExpr->x.pList!=0) ){
        /* Case 2:     expr IN (exprlist)
        **
        ** For each expression, build an index key from the evaluation and
        ** store it in the temporary table. If <expr> is a column, then use
        ** that columns affinity when building index keys. If <expr> is not
        ** a column, use numeric affinity.
        */
        int i;
        ExprList *pList = pExpr->x.pList;
        struct ExprList_item *pItem;
        int r1, r2, r3;

        if( !affinity ){
          affinity = SQLITE_AFF_NONE;
        }
        if( pKeyInfo ){
          pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
        }

        /* Loop through each expression in <exprlist>. */
        r1 = sqlite3GetTempReg(pParse);
        r2 = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp2(v, OP_Null, 0, r2);
        for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
          Expr *pE2 = pItem->pExpr;
          int iValToIns;

          /* If the expression is not constant then we will need to
          ** disable the test that was generated above that makes sure
          ** this code only executes once.  Because for a non-constant
          ** expression we need to rerun this code each time.
          */
          if( testAddr>=0 && !sqlite3ExprIsConstant(pE2) ){
            sqlite3VdbeChangeToNoop(v, testAddr);
            testAddr = -1;
          }

          /* Evaluate the expression and insert it into the temp table */
          if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){
            sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
          }else{
            r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
            if( isRowid ){
              sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
                                sqlite3VdbeCurrentAddr(v)+2);
              sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
            }else{
              sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
              sqlite3ExprCacheAffinityChange(pParse, r3, 1);
              sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2);
            }
          }
        }
        sqlite3ReleaseTempReg(pParse, r1);
        sqlite3ReleaseTempReg(pParse, r2);
      }
      if( pKeyInfo ){
        sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO_HANDOFF);
      }
      break;
    }

    case TK_EXISTS:
    case TK_SELECT:
    default: {
      /* If this has to be a scalar SELECT.  Generate code to put the
      ** value of this select in a memory cell and record the number
      ** of the memory cell in iColumn.  If this is an EXISTS, write
      ** an integer 0 (not exists) or 1 (exists) into a memory cell
      ** and record that memory cell in iColumn.
      */
      Select *pSel;                         /* SELECT statement to encode */
      SelectDest dest;                      /* How to deal with SELECt result */

      testcase( pExpr->op==TK_EXISTS );
      testcase( pExpr->op==TK_SELECT );
      assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );

      assert( ExprHasProperty(pExpr, EP_xIsSelect) );
      pSel = pExpr->x.pSelect;
      sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
      if( pExpr->op==TK_SELECT ){
        dest.eDest = SRT_Mem;
        sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm);
        VdbeComment((v, "Init subquery result"));
      }else{
        dest.eDest = SRT_Exists;
        sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
        VdbeComment((v, "Init EXISTS result"));
      }
      sqlite3ExprDelete(pParse->db, pSel->pLimit);
      pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
                                  &sqlite3IntTokens[1]);
      pSel->iLimit = 0;
      if( sqlite3Select(pParse, pSel, &dest) ){
        return 0;
      }
      rReg = dest.iSDParm;
      ExprSetIrreducible(pExpr);
      break;
    }
  }

  if( testAddr>=0 ){
    sqlite3VdbeJumpHere(v, testAddr);
  }
  sqlite3ExprCachePop(pParse, 1);

  return rReg;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %ecx, -0x44(%rbp)
movl %edx, %r15d
movq %rsi, %r13
movq %rdi, %rbx
callq 0x45b57
testq %rax, %rax
je 0x4e8ff
movq %rax, %r14
incl 0x6c(%rbx)
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
testb $0x20, 0x2(%r13)
jne 0x4e7e6
movq %rbx, %rdi
callq 0x45b57
movl 0x60(%rbx), %edx
leal 0x1(%rdx), %ecx
movl %ecx, 0x60(%rbx)
movq %rax, %rdi
movl $0x26, %esi
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x45b9e
movl %eax, %r12d
cmpb $0x2, 0x200(%rbx)
movq %r13, -0x58(%rbp)
jne 0x4e868
testl %r12d, %r12d
leaq 0x2fb63(%rip), %rax     # 0x7e360
leaq 0x2ce9d(%rip), %rdx     # 0x7b6a1
cmovnsq %rax, %rdx
movq (%rbx), %rdi
cmpb $0x48, (%r13)
leaq 0x2ce96(%rip), %rax     # 0x7b6ad
leaq 0x2ce94(%rip), %rcx     # 0x7b6b2
cmoveq %rax, %rcx
movl 0x214(%rbx), %r8d
leaq 0x2ce58(%rip), %rsi     # 0x7b688
xorl %eax, %eax
callq 0x117e2
movq %rax, %r13
movl 0x210(%rbx), %edx
movq %r14, %rdi
movl $0x96, %esi
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x45b9e
movq %r14, %rdi
movl %eax, %esi
movq %r13, %rdx
movq -0x58(%rbp), %r13
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
callq 0x11975
movb (%r13), %al
cmpb $0x48, %al
movq %r14, -0x40(%rbp)
movl %r12d, -0x34(%rbp)
jne 0x4e907
movq 0x10(%r13), %r13
testl %r15d, %r15d
je 0x4e89a
movq %r14, %rdi
movl $0x18, %esi
xorl %edx, %edx
movl %r15d, %ecx
xorl %r8d, %r8d
callq 0x45b9e
movq %r13, %rdi
callq 0x4b00f
movb %al, -0x29(%rbp)
movl 0x54(%rbx), %edx
leal 0x1(%rdx), %eax
movl %eax, 0x54(%rbx)
movq -0x58(%rbp), %r13
movl %edx, 0x2c(%r13)
xorl %ecx, %ecx
cmpl $0x0, -0x44(%rbp)
sete %cl
movq %r14, %rdi
movl $0x33, %esi
xorl %r8d, %r8d
callq 0x45b9e
movl %eax, -0x5c(%rbp)
testl %r15d, %r15d
jne 0x4e8ed
movq 0x8(%r14), %rax
testq %rax, %rax
je 0x4e8ed
movslq 0x34(%r14), %rcx
leaq (%rcx,%rcx,2), %rcx
movb $0x8, -0x15(%rax,%rcx,8)
cmpl $0x0, -0x44(%rbp)
je 0x4e9ad
xorl %r15d, %r15d
jmp 0x4e9bd
xorl %r15d, %r15d
jmp 0x4ed3d
movq 0x20(%r13), %r12
movl 0x58(%rbx), %ecx
incl %ecx
movl %ecx, 0x58(%rbx)
leaq -0x90(%rbp), %r13
movw $0x0, (%r13)
movl %ecx, 0x4(%r13)
movq $0x0, 0x8(%r13)
xorl %edx, %edx
cmpb $0x74, %al
sete %dl
leal (%rdx,%rdx,2), %eax
addl $0x3, %eax
leal (%rdx,%rdx,2), %esi
addl $0x15, %esi
movb %al, (%r13)
xorl %r15d, %r15d
movq %r14, %rdi
xorl %edx, %edx
xorl %r8d, %r8d
callq 0x45b9e
movq (%rbx), %rdi
movq 0x68(%r12), %rsi
callq 0x34068
leaq 0x44ac8(%rip), %r8      # 0x93430
movq %rbx, %rdi
movl $0x81, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x39f77
movq %rax, 0x68(%r12)
movl %r15d, 0xc(%r12)
movq %rbx, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0x3ba12
movl $0x0, %r14d
testl %eax, %eax
jne 0x4e9a2
movl -0x8c(%rbp), %r14d
jne 0x4ed3d
jmp 0x4ed0e
movq (%rbx), %rdi
movl $0x1, %esi
callq 0x35fcd
movq %rax, %r15
testb $0x8, 0x3(%r13)
jne 0x4ea13
movq 0x20(%r13), %r14
testq %r14, %r14
je 0x4ea62
cmpb $0x0, -0x29(%rbp)
jne 0x4e9db
movb $0x62, -0x29(%rbp)
testq %r15, %r15
je 0x4e9f0
movq 0x10(%r13), %rsi
movq %rbx, %rdi
callq 0x4b095
movq %rax, 0x18(%r15)
movb 0x1f(%rbx), %al
testb %al, %al
movl -0x34(%rbp), %r12d
je 0x4eaa3
decb %al
movb %al, 0x1f(%rbx)
movzbl %al, %eax
movl 0x28(%rbx,%rax,4), %eax
movl %eax, -0x38(%rbp)
jmp 0x4eaae
movq %r15, -0x50(%rbp)
movl 0x2c(%r13), %eax
leaq -0x90(%rbp), %rdx
movb $0x7, (%rdx)
movl %eax, 0x4(%rdx)
movq $0x0, 0x8(%rdx)
movb -0x29(%rbp), %al
movb %al, 0x1(%rdx)
movq 0x20(%r13), %rax
movl $0x0, 0xc(%rax)
movq 0x20(%r13), %rsi
movq %rbx, %rdi
callq 0x3ba12
movl %eax, %r15d
testl %eax, %eax
je 0x4ea6b
movq (%rbx), %rdi
movq -0x50(%rbp), %rsi
callq 0x9c3a
jmp 0x4ea8d
movq -0x40(%rbp), %r14
jmp 0x4ece5
movq 0x10(%r13), %rsi
movq 0x20(%r13), %rax
movq (%rax), %rax
movq 0x8(%rax), %rax
movq (%rax), %rdx
movq %rbx, %rdi
callq 0x4eea5
movq -0x50(%rbp), %rcx
movq %rax, 0x18(%rcx)
testl %r15d, %r15d
je 0x4ea9a
xorl %r12d, %r12d
jmp 0x4ed00
movq -0x50(%rbp), %r15
jmp 0x4ece5
movl 0x58(%rbx), %eax
incl %eax
movl %eax, -0x38(%rbp)
movl %eax, 0x58(%rbx)
movb 0x1f(%rbx), %al
testb %al, %al
movq %r15, -0x50(%rbp)
je 0x4eac7
decb %al
movb %al, 0x1f(%rbx)
movzbl %al, %eax
movl 0x28(%rbx,%rax,4), %ecx
jmp 0x4eacf
movl 0x58(%rbx), %ecx
incl %ecx
movl %ecx, 0x58(%rbx)
movq -0x40(%rbp), %rdi
movl $0x18, %esi
xorl %edx, %edx
movl %ecx, -0x30(%rbp)
xorl %r8d, %r8d
callq 0x45b9e
movl (%r14), %r15d
testl %r15d, %r15d
jle 0x4ec5d
movq 0x8(%r14), %r14
incl %r15d
movq (%r14), %r13
testl %r12d, %r12d
js 0x4eb60
xorps %xmm0, %xmm0
movaps %xmm0, -0x90(%rbp)
movaps %xmm0, -0x80(%rbp)
movq $0x0, -0x70(%rbp)
movl $0x1, -0x70(%rbp)
leaq -0x308c(%rip), %rax     # 0x4ba98
movq %rax, -0x90(%rbp)
leaq -0x3058(%rip), %rax     # 0x4bada
movq %rax, -0x88(%rbp)
leaq -0x90(%rbp), %rdi
movq %r13, %rsi
callq 0x470d7
cmpl $0x0, -0x70(%rbp)
jne 0x4eb60
movq -0x40(%rbp), %rdi
movl %r12d, %esi
callq 0x11b1d
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
cmpl $0x0, -0x44(%rbp)
je 0x4eb9d
movq %r13, %rdi
leaq -0x90(%rbp), %rsi
callq 0x4aaf6
testl %eax, %eax
je 0x4eb9d
movq -0x58(%rbp), %rax
movl 0x2c(%rax), %edx
movl -0x90(%rbp), %r8d
movq -0x40(%rbp), %rdi
movl $0x43, %esi
movl -0x30(%rbp), %ecx
callq 0x45b9e
jmp 0x4ec4c
movl %r12d, -0x34(%rbp)
movq %rbx, %rdi
movq %r13, %rsi
movl -0x38(%rbp), %edx
callq 0x4d211
movl %eax, %r13d
cmpl $0x0, -0x44(%rbp)
je 0x4ebee
movq -0x40(%rbp), %r12
movl 0x34(%r12), %ecx
addl $0x2, %ecx
movq %r12, %rdi
movl $0x21, %esi
movl %r13d, %edx
xorl %r8d, %r8d
callq 0x45b9e
movq -0x58(%rbp), %rax
movl 0x2c(%rax), %edx
movq %r12, %rdi
movl $0x42, %esi
movl -0x30(%rbp), %ecx
movl %r13d, %r8d
jmp 0x4ec43
movq -0x40(%rbp), %r12
movq %r12, %rdi
movl $0x2b, %esi
movl %r13d, %edx
movl $0x1, %ecx
movl -0x30(%rbp), %r8d
callq 0x45b9e
movq %r12, %rdi
movl %eax, %esi
leaq -0x29(%rbp), %rdx
movl $0x1, %ecx
callq 0x11975
movq %rbx, %rdi
movl %r13d, %esi
movl $0x1, %edx
callq 0x4e50d
movq -0x58(%rbp), %rax
movl 0x2c(%rax), %edx
movq %r12, %rdi
movl $0x67, %esi
movl -0x30(%rbp), %ecx
xorl %r8d, %r8d
callq 0x45b9e
movl -0x34(%rbp), %r12d
addq $0x20, %r14
decl %r15d
cmpl $0x1, %r15d
jg 0x4eaf8
cmpl $0x0, -0x38(%rbp)
movq -0x40(%rbp), %r14
movq -0x50(%rbp), %r15
je 0x4eca3
movzbl 0x1f(%rbx), %eax
cmpq $0x7, %rax
ja 0x4eca3
xorl %ecx, %ecx
movl -0x38(%rbp), %edx
cmpl %edx, 0x84(%rbx,%rcx)
je 0x4ec9e
addq $0x18, %rcx
cmpl $0xf0, %ecx
jne 0x4ec7a
leal 0x1(%rax), %ecx
movb %cl, 0x1f(%rbx)
movl -0x38(%rbp), %ecx
movl %ecx, 0x28(%rbx,%rax,4)
jmp 0x4eca3
movb $0x1, 0x7c(%rbx,%rcx)
cmpl $0x0, -0x30(%rbp)
movl %r12d, -0x34(%rbp)
je 0x4ece5
movzbl 0x1f(%rbx), %eax
cmpq $0x7, %rax
ja 0x4ece5
xorl %ecx, %ecx
movl -0x30(%rbp), %edx
cmpl %edx, 0x84(%rbx,%rcx)
je 0x4ece0
addq $0x18, %rcx
cmpl $0xf0, %ecx
jne 0x4ecbc
leal 0x1(%rax), %ecx
movb %cl, 0x1f(%rbx)
movl -0x30(%rbp), %ecx
movl %ecx, 0x28(%rbx,%rax,4)
jmp 0x4ece5
movb $0x1, 0x7c(%rbx,%rcx)
movb $0x1, %r12b
testq %r15, %r15
je 0x4ed00
movq %r14, %rdi
movl -0x5c(%rbp), %esi
movq %r15, %rdx
movl $0xfffffff0, %ecx       # imm = 0xFFFFFFF0
callq 0x11975
xorl %r14d, %r14d
movl $0x0, %r15d
testb %r12b, %r12b
je 0x4ed3d
movl -0x34(%rbp), %edx
testl %edx, %edx
js 0x4ed32
movq -0x40(%rbp), %rax
movl 0x34(%rax), %eax
cmpl %edx, %eax
jbe 0x4ed32
movq -0x40(%rbp), %rcx
movq 0x8(%rcx), %rcx
movl %edx, %edx
leaq (%rdx,%rdx,2), %rdx
movl %eax, 0x8(%rcx,%rdx,8)
movq %rbx, %rdi
callq 0x4cc3a
movl %r14d, %r15d
movl %r15d, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq