/ Check-in [2b6494b1]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Split the code generation for the RHS of IN operators and for SELECT and EXISTS expressions into two separate subroutines, because there is now little commonality between those to functions. This is intended to help make the code easier to read and maintain.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 2b6494b1509f0d0189f98aa34c990eee99c775ff57826e79b2c5b0a12b4c97ad
User & Date: drh 2018-12-23 21:27:29
Context
2018-12-24
13:34
Change the way a comparison used to detect corrupt databases in fts3 is done to avoid potential pointer overflow in 32-bit builds. check-in: 95a9a39f user: dan tags: trunk
02:34
Experimental code that tries to put the computation of subqueries inside a subroutine, and reuse that subroutine if the same subquery is evaluated more than once. Current code does not work for CHECK constraints. check-in: 6c44838a user: drh tags: reuse-subqueries
2018-12-23
21:27
Split the code generation for the RHS of IN operators and for SELECT and EXISTS expressions into two separate subroutines, because there is now little commonality between those to functions. This is intended to help make the code easier to read and maintain. check-in: 2b6494b1 user: drh tags: trunk
2018-12-22
20:32
Improve the coverage of wal.c provided by the "coverage-wal" test permutation. check-in: 62314851 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

   477    477   **
   478    478   ** If pExpr is not a TK_SELECT expression, return 0.
   479    479   */
   480    480   static int exprCodeSubselect(Parse *pParse, Expr *pExpr){
   481    481     int reg = 0;
   482    482   #ifndef SQLITE_OMIT_SUBQUERY
   483    483     if( pExpr->op==TK_SELECT ){
   484         -    reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
          484  +    reg = sqlite3CodeSubselect(pParse, pExpr);
   485    485     }
   486    486   #endif
   487    487     return reg;
   488    488   }
   489    489   
   490    490   /*
   491    491   ** Argument pVector points to a vector expression - either a TK_VECTOR
................................................................................
  2538   2538         pParse->nQueryLoop = 0;
  2539   2539         if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){
  2540   2540           eType = IN_INDEX_ROWID;
  2541   2541         }
  2542   2542       }else if( prRhsHasNull ){
  2543   2543         *prRhsHasNull = rMayHaveNull = ++pParse->nMem;
  2544   2544       }
  2545         -    sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
         2545  +    assert( pX->op==TK_IN );
         2546  +    sqlite3CodeRhsOfIN(pParse, pX, eType==IN_INDEX_ROWID);
         2547  +    if( rMayHaveNull ){
         2548  +      sqlite3SetHasNullFlag(v, pX->iTable, rMayHaveNull);
         2549  +    }
  2546   2550       pParse->nQueryLoop = savedNQueryLoop;
  2547   2551     }else{
  2548   2552       pX->iTable = iTab;
  2549   2553     }
  2550   2554   
  2551   2555     if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){
  2552   2556       int i, n;
................................................................................
  2622   2626     }else
  2623   2627   #endif
  2624   2628     {
  2625   2629       sqlite3ErrorMsg(pParse, "row value misused");
  2626   2630     }
  2627   2631   }
  2628   2632   
         2633  +#ifndef SQLITE_OMIT_SUBQUERY
  2629   2634   /*
  2630         -** Generate code for scalar subqueries used as a subquery expression, EXISTS,
  2631         -** or IN operators.  Examples:
         2635  +** Generate code that will construct an ephemeral table containing all terms
         2636  +** in the RHS of an IN operator.  The IN operator can be in either of two
         2637  +** forms:
  2632   2638   **
  2633         -**     (SELECT a FROM b)          -- subquery
  2634         -**     EXISTS (SELECT a FROM b)   -- EXISTS subquery
  2635   2639   **     x IN (4,5,11)              -- IN operator with list on right-hand side
  2636   2640   **     x IN (SELECT a FROM b)     -- IN operator with subquery on the right
  2637   2641   **
  2638         -** The pExpr parameter describes the expression that contains the IN
  2639         -** operator or subquery.
  2640         -**
  2641         -** If parameter isRowid is non-zero, then expression pExpr is guaranteed
  2642         -** to be of the form "<rowid> IN (?, ?, ?)", where <rowid> is a reference
  2643         -** to some integer key column of a table B-Tree. In this case, use an
  2644         -** intkey B-Tree to store the set of IN(...) values instead of the usual
  2645         -** (slower) variable length keys B-Tree.
  2646         -**
  2647         -** If rMayHaveNull is non-zero, that means that the operation is an IN
  2648         -** (not a SELECT or EXISTS) and that the RHS might contains NULLs.
  2649         -** All this routine does is initialize the register given by rMayHaveNull
  2650         -** to NULL.  Calling routines will take care of changing this register
  2651         -** value to non-NULL if the RHS is NULL-free.
  2652         -**
  2653         -** For a SELECT or EXISTS operator, return the register that holds the
  2654         -** result.  For a multi-column SELECT, the result is stored in a contiguous
  2655         -** array of registers and the return value is the register of the left-most
  2656         -** result column.  Return 0 for IN operators or if an error occurs.
         2642  +** The pExpr parameter is the IN operator.
         2643  +**
         2644  +** If parameter isRowid is non-zero, then LHS of the IN operator is guaranteed
         2645  +** to be a non-null integer. In this case, the ephemeral table can be an
         2646  +** table B-Tree that keyed by only integers.  The more general cases uses
         2647  +** an index B-Tree which can have arbitrary keys, but is slower to both
         2648  +** read and write.
         2649  +**
         2650  +** If the LHS expression ("x" in the examples) is a column value, or
         2651  +** the SELECT statement returns a column value, then the affinity of that
         2652  +** column is used to build the index keys. If both 'x' and the
         2653  +** SELECT... statement are columns, then numeric affinity is used
         2654  +** if either column has NUMERIC or INTEGER affinity. If neither
         2655  +** 'x' nor the SELECT... statement are columns, then numeric affinity
         2656  +** is used.
         2657  +*/
         2658  +void sqlite3CodeRhsOfIN(
         2659  +  Parse *pParse,          /* Parsing context */
         2660  +  Expr *pExpr,            /* The IN operator */
         2661  +  int isRowid             /* If true, LHS is a rowid */
         2662  +){
         2663  +  int jmpIfDynamic = -1;      /* One-time test address */
         2664  +  int addr;                   /* Address of OP_OpenEphemeral instruction */
         2665  +  Expr *pLeft;                /* the LHS of the IN operator */
         2666  +  KeyInfo *pKeyInfo = 0;      /* Key information */
         2667  +  int nVal;                   /* Size of vector pLeft */
         2668  +  Vdbe *v;                    /* The prepared statement under construction */
         2669  +
         2670  +  v = sqlite3GetVdbe(pParse);
         2671  +  assert( v!=0 );
         2672  +
         2673  +  /* The evaluation of the RHS of IN operator must be repeated every time it
         2674  +  ** is encountered if any of the following is true:
         2675  +  **
         2676  +  **    *  The right-hand side is a correlated subquery
         2677  +  **    *  The right-hand side is an expression list containing variables
         2678  +  **    *  We are inside a trigger
         2679  +  **
         2680  +  ** If all of the above are false, then we can run this code just once
         2681  +  ** save the results, and reuse the same result on subsequent invocations.
         2682  +  */
         2683  +  if( !ExprHasProperty(pExpr, EP_VarSelect) ){
         2684  +    jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
         2685  +  }
         2686  +
         2687  +  /* Check to see if this is a vector IN operator */
         2688  +  pLeft = pExpr->pLeft;
         2689  +  nVal = sqlite3ExprVectorSize(pLeft);
         2690  +  assert( !isRowid || nVal==1 );
         2691  +
         2692  +  /* Construct the ephemeral table that will contain the content of
         2693  +  ** RHS of the IN operator.
         2694  +  */
         2695  +  pExpr->iTable = pParse->nTab++;
         2696  +  addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, 
         2697  +      pExpr->iTable, (isRowid?0:nVal));
         2698  +  pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
         2699  +
         2700  +  if( ExprHasProperty(pExpr, EP_xIsSelect) ){
         2701  +    /* Case 1:     expr IN (SELECT ...)
         2702  +    **
         2703  +    ** Generate code to write the results of the select into the temporary
         2704  +    ** table allocated and opened above.
         2705  +    */
         2706  +    Select *pSelect = pExpr->x.pSelect;
         2707  +    ExprList *pEList = pSelect->pEList;
         2708  +
         2709  +    ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY",
         2710  +        jmpIfDynamic>=0?"":"CORRELATED "
         2711  +    ));
         2712  +    assert( !isRowid );
         2713  +    /* If the LHS and RHS of the IN operator do not match, that
         2714  +    ** error will have been caught long before we reach this point. */
         2715  +    if( ALWAYS(pEList->nExpr==nVal) ){
         2716  +      SelectDest dest;
         2717  +      int i;
         2718  +      sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
         2719  +      dest.zAffSdst = exprINAffinity(pParse, pExpr);
         2720  +      pSelect->iLimit = 0;
         2721  +      testcase( pSelect->selFlags & SF_Distinct );
         2722  +      testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
         2723  +      if( sqlite3Select(pParse, pSelect, &dest) ){
         2724  +        sqlite3DbFree(pParse->db, dest.zAffSdst);
         2725  +        sqlite3KeyInfoUnref(pKeyInfo);
         2726  +        return;
         2727  +      }
         2728  +      sqlite3DbFree(pParse->db, dest.zAffSdst);
         2729  +      assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
         2730  +      assert( pEList!=0 );
         2731  +      assert( pEList->nExpr>0 );
         2732  +      assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
         2733  +      for(i=0; i<nVal; i++){
         2734  +        Expr *p = sqlite3VectorFieldSubexpr(pLeft, i);
         2735  +        pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
         2736  +            pParse, p, pEList->a[i].pExpr
         2737  +        );
         2738  +      }
         2739  +    }
         2740  +  }else if( ALWAYS(pExpr->x.pList!=0) ){
         2741  +    /* Case 2:     expr IN (exprlist)
         2742  +    **
         2743  +    ** For each expression, build an index key from the evaluation and
         2744  +    ** store it in the temporary table. If <expr> is a column, then use
         2745  +    ** that columns affinity when building index keys. If <expr> is not
         2746  +    ** a column, use numeric affinity.
         2747  +    */
         2748  +    char affinity;            /* Affinity of the LHS of the IN */
         2749  +    int i;
         2750  +    ExprList *pList = pExpr->x.pList;
         2751  +    struct ExprList_item *pItem;
         2752  +    int r1, r2, r3;
         2753  +    affinity = sqlite3ExprAffinity(pLeft);
         2754  +    if( !affinity ){
         2755  +      affinity = SQLITE_AFF_BLOB;
         2756  +    }
         2757  +    if( pKeyInfo ){
         2758  +      assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
         2759  +      pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
         2760  +    }
         2761  +
         2762  +    /* Loop through each expression in <exprlist>. */
         2763  +    r1 = sqlite3GetTempReg(pParse);
         2764  +    r2 = sqlite3GetTempReg(pParse);
         2765  +    if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC);
         2766  +    for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
         2767  +      Expr *pE2 = pItem->pExpr;
         2768  +      int iValToIns;
         2769  +
         2770  +      /* If the expression is not constant then we will need to
         2771  +      ** disable the test that was generated above that makes sure
         2772  +      ** this code only executes once.  Because for a non-constant
         2773  +      ** expression we need to rerun this code each time.
         2774  +      */
         2775  +      if( jmpIfDynamic>=0 && !sqlite3ExprIsConstant(pE2) ){
         2776  +        sqlite3VdbeChangeToNoop(v, jmpIfDynamic);
         2777  +        jmpIfDynamic = -1;
         2778  +      }
         2779  +
         2780  +      /* Evaluate the expression and insert it into the temp table */
         2781  +      if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){
         2782  +        sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
         2783  +      }else{
         2784  +        r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
         2785  +        if( isRowid ){
         2786  +          sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
         2787  +                            sqlite3VdbeCurrentAddr(v)+2);
         2788  +          VdbeCoverage(v);
         2789  +          sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
         2790  +        }else{
         2791  +          sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
         2792  +          sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1);
         2793  +        }
         2794  +      }
         2795  +    }
         2796  +    sqlite3ReleaseTempReg(pParse, r1);
         2797  +    sqlite3ReleaseTempReg(pParse, r2);
         2798  +  }
         2799  +  if( pKeyInfo ){
         2800  +    sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
         2801  +  }
         2802  +  if( jmpIfDynamic>=0 ){
         2803  +    sqlite3VdbeJumpHere(v, jmpIfDynamic);
         2804  +  }
         2805  +}
         2806  +#endif /* SQLITE_OMIT_SUBQUERY */
         2807  +
         2808  +/*
         2809  +** Generate code for scalar subqueries used as a subquery expression
         2810  +** or EXISTS operator:
         2811  +**
         2812  +**     (SELECT a FROM b)          -- subquery
         2813  +**     EXISTS (SELECT a FROM b)   -- EXISTS subquery
         2814  +**
         2815  +** The pExpr parameter is the SELECT or EXISTS operator to be coded.
         2816  +**
         2817  +** The register that holds the result.  For a multi-column SELECT, 
         2818  +** the result is stored in a contiguous array of registers and the
         2819  +** return value is the register of the left-most result column.
         2820  +** Return 0 if an error occurs.
  2657   2821   */
  2658   2822   #ifndef SQLITE_OMIT_SUBQUERY
  2659         -int sqlite3CodeSubselect(
  2660         -  Parse *pParse,          /* Parsing context */
  2661         -  Expr *pExpr,            /* The IN, SELECT, or EXISTS operator */
  2662         -  int rHasNullFlag,       /* Register that records whether NULLs exist in RHS */
  2663         -  int isRowid             /* If true, LHS of IN operator is a rowid */
  2664         -){
  2665         -  int jmpIfDynamic = -1;                      /* One-time test address */
  2666         -  int rReg = 0;                           /* Register storing resulting */
         2823  +int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
         2824  +  int jmpIfDynamic = -1;      /* One-time test address */
         2825  +  int rReg = 0;               /* Register storing resulting */
         2826  +  Select *pSel;               /* SELECT statement to encode */
         2827  +  SelectDest dest;            /* How to deal with SELECT result */
         2828  +  int nReg;                   /* Registers to allocate */
         2829  +  Expr *pLimit;               /* New limit expression */
  2667   2830     Vdbe *v = sqlite3GetVdbe(pParse);
  2668         -  if( NEVER(v==0) ) return 0;
         2831  +  assert( v!=0 );
  2669   2832   
  2670         -  /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it
         2833  +  /* The evaluation of the EXISTS/SELECT must be repeated every time it
  2671   2834     ** is encountered if any of the following is true:
  2672   2835     **
  2673   2836     **    *  The right-hand side is a correlated subquery
  2674   2837     **    *  The right-hand side is an expression list containing variables
  2675   2838     **    *  We are inside a trigger
  2676   2839     **
  2677   2840     ** If all of the above are false, then we can run this code just once
  2678   2841     ** save the results, and reuse the same result on subsequent invocations.
  2679   2842     */
  2680   2843     if( !ExprHasProperty(pExpr, EP_VarSelect) ){
  2681   2844       jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
  2682   2845     }
  2683         -
  2684         -  switch( pExpr->op ){
  2685         -    case TK_IN: {
  2686         -      int addr;                   /* Address of OP_OpenEphemeral instruction */
  2687         -      Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
  2688         -      KeyInfo *pKeyInfo = 0;      /* Key information */
  2689         -      int nVal;                   /* Size of vector pLeft */
  2690         -      
  2691         -      nVal = sqlite3ExprVectorSize(pLeft);
  2692         -      assert( !isRowid || nVal==1 );
  2693         -
  2694         -      /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
  2695         -      ** expression it is handled the same way.  An ephemeral table is 
  2696         -      ** filled with index keys representing the results from the 
  2697         -      ** SELECT or the <exprlist>.
  2698         -      **
  2699         -      ** If the 'x' expression is a column value, or the SELECT...
  2700         -      ** statement returns a column value, then the affinity of that
  2701         -      ** column is used to build the index keys. If both 'x' and the
  2702         -      ** SELECT... statement are columns, then numeric affinity is used
  2703         -      ** if either column has NUMERIC or INTEGER affinity. If neither
  2704         -      ** 'x' nor the SELECT... statement are columns, then numeric affinity
  2705         -      ** is used.
  2706         -      */
  2707         -      pExpr->iTable = pParse->nTab++;
  2708         -      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, 
  2709         -          pExpr->iTable, (isRowid?0:nVal));
  2710         -      pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
  2711         -
  2712         -      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
  2713         -        /* Case 1:     expr IN (SELECT ...)
  2714         -        **
  2715         -        ** Generate code to write the results of the select into the temporary
  2716         -        ** table allocated and opened above.
  2717         -        */
  2718         -        Select *pSelect = pExpr->x.pSelect;
  2719         -        ExprList *pEList = pSelect->pEList;
  2720         -
  2721         -        ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY",
  2722         -            jmpIfDynamic>=0?"":"CORRELATED "
  2723         -        ));
  2724         -        assert( !isRowid );
  2725         -        /* If the LHS and RHS of the IN operator do not match, that
  2726         -        ** error will have been caught long before we reach this point. */
  2727         -        if( ALWAYS(pEList->nExpr==nVal) ){
  2728         -          SelectDest dest;
  2729         -          int i;
  2730         -          sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
  2731         -          dest.zAffSdst = exprINAffinity(pParse, pExpr);
  2732         -          pSelect->iLimit = 0;
  2733         -          testcase( pSelect->selFlags & SF_Distinct );
  2734         -          testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
  2735         -          if( sqlite3Select(pParse, pSelect, &dest) ){
  2736         -            sqlite3DbFree(pParse->db, dest.zAffSdst);
  2737         -            sqlite3KeyInfoUnref(pKeyInfo);
  2738         -            return 0;
  2739         -          }
  2740         -          sqlite3DbFree(pParse->db, dest.zAffSdst);
  2741         -          assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
  2742         -          assert( pEList!=0 );
  2743         -          assert( pEList->nExpr>0 );
  2744         -          assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
  2745         -          for(i=0; i<nVal; i++){
  2746         -            Expr *p = sqlite3VectorFieldSubexpr(pLeft, i);
  2747         -            pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
  2748         -                pParse, p, pEList->a[i].pExpr
  2749         -            );
  2750         -          }
  2751         -        }
  2752         -      }else if( ALWAYS(pExpr->x.pList!=0) ){
  2753         -        /* Case 2:     expr IN (exprlist)
  2754         -        **
  2755         -        ** For each expression, build an index key from the evaluation and
  2756         -        ** store it in the temporary table. If <expr> is a column, then use
  2757         -        ** that columns affinity when building index keys. If <expr> is not
  2758         -        ** a column, use numeric affinity.
  2759         -        */
  2760         -        char affinity;            /* Affinity of the LHS of the IN */
  2761         -        int i;
  2762         -        ExprList *pList = pExpr->x.pList;
  2763         -        struct ExprList_item *pItem;
  2764         -        int r1, r2, r3;
  2765         -        affinity = sqlite3ExprAffinity(pLeft);
  2766         -        if( !affinity ){
  2767         -          affinity = SQLITE_AFF_BLOB;
  2768         -        }
  2769         -        if( pKeyInfo ){
  2770         -          assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
  2771         -          pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
  2772         -        }
  2773         -
  2774         -        /* Loop through each expression in <exprlist>. */
  2775         -        r1 = sqlite3GetTempReg(pParse);
  2776         -        r2 = sqlite3GetTempReg(pParse);
  2777         -        if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC);
  2778         -        for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
  2779         -          Expr *pE2 = pItem->pExpr;
  2780         -          int iValToIns;
  2781         -
  2782         -          /* If the expression is not constant then we will need to
  2783         -          ** disable the test that was generated above that makes sure
  2784         -          ** this code only executes once.  Because for a non-constant
  2785         -          ** expression we need to rerun this code each time.
  2786         -          */
  2787         -          if( jmpIfDynamic>=0 && !sqlite3ExprIsConstant(pE2) ){
  2788         -            sqlite3VdbeChangeToNoop(v, jmpIfDynamic);
  2789         -            jmpIfDynamic = -1;
  2790         -          }
  2791         -
  2792         -          /* Evaluate the expression and insert it into the temp table */
  2793         -          if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){
  2794         -            sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
  2795         -          }else{
  2796         -            r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
  2797         -            if( isRowid ){
  2798         -              sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
  2799         -                                sqlite3VdbeCurrentAddr(v)+2);
  2800         -              VdbeCoverage(v);
  2801         -              sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
  2802         -            }else{
  2803         -              sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
  2804         -              sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1);
  2805         -            }
  2806         -          }
  2807         -        }
  2808         -        sqlite3ReleaseTempReg(pParse, r1);
  2809         -        sqlite3ReleaseTempReg(pParse, r2);
  2810         -      }
  2811         -      if( pKeyInfo ){
  2812         -        sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
  2813         -      }
  2814         -      break;
  2815         -    }
  2816         -
  2817         -    case TK_EXISTS:
  2818         -    case TK_SELECT:
  2819         -    default: {
  2820         -      /* Case 3:    (SELECT ... FROM ...)
  2821         -      **     or:    EXISTS(SELECT ... FROM ...)
  2822         -      **
  2823         -      ** For a SELECT, generate code to put the values for all columns of
  2824         -      ** the first row into an array of registers and return the index of
  2825         -      ** the first register.
  2826         -      **
  2827         -      ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists)
  2828         -      ** into a register and return that register number.
  2829         -      **
  2830         -      ** In both cases, the query is augmented with "LIMIT 1".  Any 
  2831         -      ** preexisting limit is discarded in place of the new LIMIT 1.
  2832         -      */
  2833         -      Select *pSel;                         /* SELECT statement to encode */
  2834         -      SelectDest dest;                      /* How to deal with SELECT result */
  2835         -      int nReg;                             /* Registers to allocate */
  2836         -      Expr *pLimit;                         /* New limit expression */
  2837         -
  2838         -      testcase( pExpr->op==TK_EXISTS );
  2839         -      testcase( pExpr->op==TK_SELECT );
  2840         -      assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
  2841         -      assert( ExprHasProperty(pExpr, EP_xIsSelect) );
  2842         -
  2843         -      pSel = pExpr->x.pSelect;
  2844         -      ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY",
  2845         -            jmpIfDynamic>=0?"":"CORRELATED "));
  2846         -      nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
  2847         -      sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
  2848         -      pParse->nMem += nReg;
  2849         -      if( pExpr->op==TK_SELECT ){
  2850         -        dest.eDest = SRT_Mem;
  2851         -        dest.iSdst = dest.iSDParm;
  2852         -        dest.nSdst = nReg;
  2853         -        sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
  2854         -        VdbeComment((v, "Init subquery result"));
  2855         -      }else{
  2856         -        dest.eDest = SRT_Exists;
  2857         -        sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
  2858         -        VdbeComment((v, "Init EXISTS result"));
  2859         -      }
  2860         -      pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
  2861         -      if( pSel->pLimit ){
  2862         -        sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
  2863         -        pSel->pLimit->pLeft = pLimit;
  2864         -      }else{
  2865         -        pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
  2866         -      }
  2867         -      pSel->iLimit = 0;
  2868         -      if( sqlite3Select(pParse, pSel, &dest) ){
  2869         -        return 0;
  2870         -      }
  2871         -      rReg = dest.iSDParm;
  2872         -      ExprSetVVAProperty(pExpr, EP_NoReduce);
  2873         -      break;
  2874         -    }
  2875         -  }
  2876         -
  2877         -  if( rHasNullFlag ){
  2878         -    sqlite3SetHasNullFlag(v, pExpr->iTable, rHasNullFlag);
  2879         -  }
         2846  +  
         2847  +  /* For a SELECT, generate code to put the values for all columns of
         2848  +  ** the first row into an array of registers and return the index of
         2849  +  ** the first register.
         2850  +  **
         2851  +  ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists)
         2852  +  ** into a register and return that register number.
         2853  +  **
         2854  +  ** In both cases, the query is augmented with "LIMIT 1".  Any 
         2855  +  ** preexisting limit is discarded in place of the new LIMIT 1.
         2856  +  */
         2857  +  testcase( pExpr->op==TK_EXISTS );
         2858  +  testcase( pExpr->op==TK_SELECT );
         2859  +  assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
         2860  +  assert( ExprHasProperty(pExpr, EP_xIsSelect) );
         2861  +
         2862  +  pSel = pExpr->x.pSelect;
         2863  +  ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY",
         2864  +        jmpIfDynamic>=0?"":"CORRELATED "));
         2865  +  nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
         2866  +  sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
         2867  +  pParse->nMem += nReg;
         2868  +  if( pExpr->op==TK_SELECT ){
         2869  +    dest.eDest = SRT_Mem;
         2870  +    dest.iSdst = dest.iSDParm;
         2871  +    dest.nSdst = nReg;
         2872  +    sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
         2873  +    VdbeComment((v, "Init subquery result"));
         2874  +  }else{
         2875  +    dest.eDest = SRT_Exists;
         2876  +    sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
         2877  +    VdbeComment((v, "Init EXISTS result"));
         2878  +  }
         2879  +  pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
         2880  +  if( pSel->pLimit ){
         2881  +    sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
         2882  +    pSel->pLimit->pLeft = pLimit;
         2883  +  }else{
         2884  +    pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
         2885  +  }
         2886  +  pSel->iLimit = 0;
         2887  +  if( sqlite3Select(pParse, pSel, &dest) ){
         2888  +    return 0;
         2889  +  }
         2890  +  rReg = dest.iSDParm;
         2891  +  ExprSetVVAProperty(pExpr, EP_NoReduce);
  2880   2892   
  2881   2893     if( jmpIfDynamic>=0 ){
  2882   2894       sqlite3VdbeJumpHere(v, jmpIfDynamic);
  2883   2895     }
  2884   2896   
  2885   2897     return rReg;
  2886   2898   }
................................................................................
  3339   3351       iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable);
  3340   3352     }else{
  3341   3353       *piFreeable = 0;
  3342   3354       if( p->op==TK_SELECT ){
  3343   3355   #if SQLITE_OMIT_SUBQUERY
  3344   3356         iResult = 0;
  3345   3357   #else
  3346         -      iResult = sqlite3CodeSubselect(pParse, p, 0, 0);
         3358  +      iResult = sqlite3CodeSubselect(pParse, p);
  3347   3359   #endif
  3348   3360       }else{
  3349   3361         int i;
  3350   3362         iResult = pParse->nMem+1;
  3351   3363         pParse->nMem += nResult;
  3352   3364         for(i=0; i<nResult; i++){
  3353   3365           sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult);
................................................................................
  3813   3825       case TK_SELECT: {
  3814   3826         int nCol;
  3815   3827         testcase( op==TK_EXISTS );
  3816   3828         testcase( op==TK_SELECT );
  3817   3829         if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
  3818   3830           sqlite3SubselectError(pParse, nCol, 1);
  3819   3831         }else{
  3820         -        return sqlite3CodeSubselect(pParse, pExpr, 0, 0);
         3832  +        return sqlite3CodeSubselect(pParse, pExpr);
  3821   3833         }
  3822   3834         break;
  3823   3835       }
  3824   3836       case TK_SELECT_COLUMN: {
  3825   3837         int n;
  3826   3838         if( pExpr->pLeft->iTable==0 ){
  3827         -        pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0);
         3839  +        pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
  3828   3840         }
  3829   3841         assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT );
  3830   3842         if( pExpr->iTable
  3831   3843          && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft)) 
  3832   3844         ){
  3833   3845           sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
  3834   3846                                   pExpr->iTable, n);

Changes to src/sqliteInt.h.

  4254   4254   void sqlite3Reindex(Parse*, Token*, Token*);
  4255   4255   void sqlite3AlterFunctions(void);
  4256   4256   void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
  4257   4257   void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
  4258   4258   int sqlite3GetToken(const unsigned char *, int *);
  4259   4259   void sqlite3NestedParse(Parse*, const char*, ...);
  4260   4260   void sqlite3ExpirePreparedStatements(sqlite3*, int);
  4261         -int sqlite3CodeSubselect(Parse*, Expr *, int, int);
         4261  +void sqlite3CodeRhsOfIN(Parse*, Expr*, int);
         4262  +int sqlite3CodeSubselect(Parse*, Expr*);
  4262   4263   void sqlite3SelectPrep(Parse*, Select*, NameContext*);
  4263   4264   void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
  4264   4265   int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
  4265   4266   int sqlite3ResolveExprNames(NameContext*, Expr*);
  4266   4267   int sqlite3ResolveExprListNames(NameContext*, ExprList*);
  4267   4268   void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
  4268   4269   void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);

Changes to src/wherecode.c.

  1072   1072   */
  1073   1073   static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
  1074   1074     assert( nReg>0 );
  1075   1075     if( p && sqlite3ExprIsVector(p) ){
  1076   1076   #ifndef SQLITE_OMIT_SUBQUERY
  1077   1077       if( (p->flags & EP_xIsSelect) ){
  1078   1078         Vdbe *v = pParse->pVdbe;
  1079         -      int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0);
         1079  +      int iSelect;
         1080  +      assert( p->op==TK_SELECT );
         1081  +      iSelect = sqlite3CodeSubselect(pParse, p);
  1080   1082         sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1);
  1081   1083       }else
  1082   1084   #endif
  1083   1085       {
  1084   1086         int i;
  1085   1087         ExprList *pList = p->x.pList;
  1086   1088         assert( nReg<=pList->nExpr );