/ Check-in [d8feea7d]
Login

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

Overview
Comment:Change the way TK_SELECT_COLUMN is handled so that the subquery is only generated once even if part of the vector comparison is used for indexing and the other part is now. This change also is a pathway to vector assignment in UPDATE statements.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | rowvalue
Files: files | file ages | folders
SHA1: d8feea7dcde83179bff303072426561cfe825e58
User & Date: drh 2016-08-20 00:07:01
Context
2016-08-20
00:51
Add support for vector assignments in the SET clause of an UPDATE statement. check-in: f320d47d user: drh tags: rowvalue
00:07
Change the way TK_SELECT_COLUMN is handled so that the subquery is only generated once even if part of the vector comparison is used for indexing and the other part is now. This change also is a pathway to vector assignment in UPDATE statements. check-in: d8feea7d user: drh tags: rowvalue
2016-08-19
19:58
Replace the magic number (-2) with its symbol XN_EXPR in the exprMightBeIndexed() routine. No logic changes. check-in: d4a5af69 user: drh tags: rowvalue
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

   330    330       return pExpr->x.pSelect->pEList->nExpr;
   331    331     }
   332    332     return pExpr->x.pList->nExpr;
   333    333   }
   334    334   
   335    335   #ifndef SQLITE_OMIT_SUBQUERY
   336    336   /*
   337         -** If the expression passed as the first argument is a TK_VECTOR, return
   338         -** a pointer to the i'th field of the vector. Or, if the first argument
   339         -** points to a sub-select that returns more than one column, return a 
   340         -** pointer to the i'th returned column value. Otherwise, return a copy 
   341         -** of the first argument.
          337  +** Interpret the pVector input as a vector expression.  If pVector is
          338  +** an ordinary scalar expression, treat it as a vector of size 1.
          339  +**
          340  +** Return a pointer to a subexpression of pVector that is the i-th
          341  +** column of the vector (numbered starting with 0).  The caller must
          342  +** ensure that i is within range.
          343  +**
          344  +** pVector retains ownership of the returned subexpression.
          345  +**
          346  +** If the vector is a (SELECT ...) then the expression returned is
          347  +** just the expression for the i-th term of the result set, and is
          348  +** necessarily ready to be evaluated because the table cursor might
          349  +** not have been positioned yet.
   342    350   */
   343         -Expr *sqlite3ExprVectorField(Expr *pVector, int i){
          351  +Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
   344    352     assert( i<sqlite3ExprVectorSize(pVector) );
   345    353     if( sqlite3ExprIsVector(pVector) ){
   346    354       if( pVector->op==TK_SELECT ){
   347    355         return pVector->x.pSelect->pEList->a[i].pExpr;
   348    356       }else{
   349    357         return pVector->x.pList->a[i].pExpr;
   350    358       }
   351    359     }
   352    360     return pVector;
   353    361   }
   354         -#endif
          362  +#endif /* !defined(SQLITE_OMIT_SUBQUERY) */
          363  +
          364  +#ifndef SQLITE_OMIT_SUBQUERY
          365  +/*
          366  +** Compute and return a new Expr object which when passed to
          367  +** sqlite3ExprCode() will generate all necessary code to compute
          368  +** the iField-th column of the vector expression pVector.
          369  +**
          370  +** The caller owns the returned Expr object and is responsible for
          371  +** ensuring that the returned value eventually gets freed.
          372  +**
          373  +** Ownership of pVector is controlled by the takeOwnership parameter.  If
          374  +** takeOwnership is true, this routine takes responsibility for freeing
          375  +** pVector, and may do so before returning, hence the caller must not reference
          376  +** pVector again.  If takeOwnership is false, then the caller takes
          377  +** responsibility for freeing pVector and must ensure the pVector remains
          378  +** valid as long as the returned value remains in use.
          379  +*/
          380  +Expr *sqlite3ExprForVectorField(
          381  +  Parse *pParse,       /* Parsing context */
          382  +  Expr *pVector,       /* The vector.  List of expressions or a sub-SELECT */
          383  +  int iField,          /* Which column of the vector to return */
          384  +  int takeOwnership    /* True to take ownership of pVector before returning */
          385  +){
          386  +  Expr *pRet;
          387  +  assert( sqlite3ExprIsVector(pVector) );
          388  +  /* FIXME: Add support for takeOwnership!=0 */ assert( takeOwnership==0 );
          389  +  if( pVector->flags & EP_xIsSelect ){
          390  +    /* The TK_SELECT_COLUMN Expr node:
          391  +    **
          392  +    ** pLeft:           pVector containing TK_SELECT
          393  +    ** pRight:          pVector if ownership taken
          394  +    ** iColumn:         Index of a column in pVector
          395  +    ** pLeft->iTable:   First in an array of register holding result, or 0
          396  +    **                  if the result is not yet computed.
          397  +    **
          398  +    ** sqlite3ExprDelete() specifically skips the recursive delete of
          399  +    ** pLeft on TK_SELECT_COLUMN nodes.  But pRight is followed, so pVector
          400  +    ** is included on pRight if ownership is taken.  Typically there will
          401  +    ** be multiple TK_SELECT_COLUMN nodes with the same pLeft pointer to 
          402  +    ** the pVector, but only one of them will own the pVector.
          403  +    */
          404  +    pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, pVector, 0, 0);
          405  +    if( pRet ) pRet->iColumn = iField;
          406  +    assert( pRet==0 || pRet->iTable==0 );
          407  +  }else{
          408  +    pRet = sqlite3ExprDup(pParse->db, pVector->x.pList->a[iField].pExpr, 0);
          409  +  }
          410  +  return pRet;
          411  +}
          412  +#endif /* !define(SQLITE_OMIT_SUBQUERY) */
   355    413   
   356    414   /*
   357    415   ** If expression pExpr is of type TK_SELECT, generate code to evaluate
   358    416   ** it. Return the register in which the result is stored (or, if the 
   359    417   ** sub-select returns more than one column, the first in an array
   360    418   ** of registers in which the result is stored).
   361    419   **
................................................................................
  2021   2079         int affinity_ok = 1;
  2022   2080         int i;
  2023   2081   
  2024   2082         /* Check that the affinity that will be used to perform each 
  2025   2083         ** comparison is the same as the affinity of each column. If
  2026   2084         ** it not, it is not possible to use any index.  */
  2027   2085         for(i=0; i<nExpr && affinity_ok; i++){
  2028         -        Expr *pLhs = sqlite3ExprVectorField(pX->pLeft, i);
         2086  +        Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
  2029   2087           int iCol = pEList->a[i].pExpr->iColumn;
  2030   2088           char idxaff = pTab->aCol[iCol].affinity;
  2031   2089           char cmpaff = sqlite3CompareAffinity(pLhs, idxaff);
  2032   2090           switch( cmpaff ){
  2033   2091             case SQLITE_AFF_BLOB:
  2034   2092               break;
  2035   2093             case SQLITE_AFF_TEXT:
................................................................................
  2047   2105         for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
  2048   2106           if( pIdx->nKeyCol<nExpr ) continue;
  2049   2107           if( mustBeUnique && (pIdx->nKeyCol!=nExpr || !IsUniqueIndex(pIdx)) ){
  2050   2108             continue;
  2051   2109           }
  2052   2110   
  2053   2111           for(i=0; i<nExpr; i++){
  2054         -          Expr *pLhs = sqlite3ExprVectorField(pX->pLeft, i);
         2112  +          Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
  2055   2113             Expr *pRhs = pEList->a[i].pExpr;
  2056   2114             CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
  2057   2115             int j;
  2058   2116   
  2059   2117             assert( pReq || pParse->nErr );
  2060   2118             if( pReq==0 ) break;
  2061   2119   
................................................................................
  2155   2213     char *zRet;
  2156   2214   
  2157   2215     assert( pExpr->op==TK_IN );
  2158   2216     zRet = sqlite3DbMallocZero(pParse->db, nVal+1);
  2159   2217     if( zRet ){
  2160   2218       int i;
  2161   2219       for(i=0; i<nVal; i++){
  2162         -      Expr *pA = sqlite3ExprVectorField(pLeft, i);
         2220  +      Expr *pA = sqlite3VectorFieldSubexpr(pLeft, i);
  2163   2221         char a = sqlite3ExprAffinity(pA);
  2164   2222         if( pSelect ){
  2165   2223           zRet[i] = sqlite3CompareAffinity(pSelect->pEList->a[i].pExpr, a);
  2166   2224         }else{
  2167   2225           zRet[i] = a;
  2168   2226         }
  2169   2227       }
................................................................................
  2309   2367             }
  2310   2368             sqlite3DbFree(pParse->db, dest.zAffSdst);
  2311   2369             assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
  2312   2370             assert( pEList!=0 );
  2313   2371             assert( pEList->nExpr>0 );
  2314   2372             assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
  2315   2373             for(i=0; i<nVal; i++){
  2316         -            Expr *p = (nVal>1) ? sqlite3ExprVectorField(pLeft, i) : pLeft;
         2374  +            Expr *p = (nVal>1) ? sqlite3VectorFieldSubexpr(pLeft, i) : pLeft;
  2317   2375               pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
  2318   2376                   pParse, p, pEList->a[i].pExpr
  2319   2377               );
  2320   2378             }
  2321   2379           }
  2322   2380         }else if( ALWAYS(pExpr->x.pList!=0) ){
  2323   2381           /* Case 2:     expr IN (exprlist)
................................................................................
  2549   2607     if( nVector>1 && (pLeft->flags & EP_xIsSelect) ){
  2550   2608       int regSelect = sqlite3CodeSubselect(pParse, pLeft, 0, 0);
  2551   2609       for(i=0; i<nVector; i++){
  2552   2610         sqlite3VdbeAddOp3(v, OP_Copy, regSelect+i, r1+aiMap[i], 0);
  2553   2611       }
  2554   2612     }else{
  2555   2613       for(i=0; i<nVector; i++){
  2556         -      Expr *pLhs = sqlite3ExprVectorField(pLeft, i);
         2614  +      Expr *pLhs = sqlite3VectorFieldSubexpr(pLeft, i);
  2557   2615         sqlite3ExprCode(pParse, pLhs, r1+aiMap[i]);
  2558   2616       }
  2559   2617     }
  2560   2618   
  2561   2619     /* If sqlite3FindInIndex() did not find or create an index that is
  2562   2620     ** suitable for evaluating the IN operator, then evaluate using a
  2563   2621     ** sequence of comparisons.
................................................................................
  2608   2666       **
  2609   2667       ** Otherwise, if NULL and false are handled differently, and the
  2610   2668       ** IN(...) operation is not a vector operation, and the LHS of the
  2611   2669       ** operator is NULL, then the result is false if the index is 
  2612   2670       ** completely empty, or NULL otherwise.  */
  2613   2671       if( destIfNull==destIfFalse ){
  2614   2672         for(i=0; i<nVector; i++){
  2615         -        Expr *p = sqlite3ExprVectorField(pExpr->pLeft, i);
         2673  +        Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
  2616   2674           if( sqlite3ExprCanBeNull(p) ){
  2617   2675             sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull);
  2618   2676             VdbeCoverage(v);
  2619   2677           }
  2620   2678         }
  2621   2679       }else if( nVector==1 && sqlite3ExprCanBeNull(pExpr->pLeft) ){
  2622   2680         int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v);
................................................................................
  2650   2708           addrNext = 1+sqlite3VdbeAddOp2(v, OP_Rewind, iIdx, destIfFalse);
  2651   2709           VdbeCoverage(v);
  2652   2710   
  2653   2711           for(i=0; i<nVector; i++){
  2654   2712             Expr *p;
  2655   2713             CollSeq *pColl;
  2656   2714             int r2 = sqlite3GetTempReg(pParse);
  2657         -          p = sqlite3ExprVectorField(pLeft, i);
         2715  +          p = sqlite3VectorFieldSubexpr(pLeft, i);
  2658   2716             pColl = sqlite3ExprCollSeq(pParse, p);
  2659   2717   
  2660   2718             sqlite3VdbeAddOp3(v, OP_Column, iIdx, i, r2);
  2661   2719             sqlite3VdbeAddOp4(v, OP_Eq, r1+i, 0, r2, (void*)pColl,P4_COLLSEQ);
  2662   2720             sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
  2663   2721             VdbeCoverage(v);
  2664   2722             sqlite3VdbeAddOp2(v, OP_Next, iIdx, addrNext);
................................................................................
  2670   2728           sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
  2671   2729   
  2672   2730           /* The key was found in the index. If it contains any NULL values,
  2673   2731           ** then the result of the IN(...) operator is NULL. Otherwise, the
  2674   2732           ** result is 1.  */
  2675   2733           sqlite3VdbeJumpHere(v, addr);
  2676   2734           for(i=0; i<nVector; i++){
  2677         -          Expr *p = sqlite3ExprVectorField(pExpr->pLeft, i);
         2735  +          Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
  2678   2736             if( sqlite3ExprCanBeNull(p) ){
  2679   2737               sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull);
  2680   2738               VdbeCoverage(v);
  2681   2739             }
  2682   2740           }
  2683   2741   
  2684   2742         }else if( rRhsHasNull==0 ){
................................................................................
  3505   3563         testcase( op==TK_SELECT );
  3506   3564         if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
  3507   3565           sqlite3SubselectError(pParse, nCol, 1);
  3508   3566         }else{
  3509   3567           inReg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
  3510   3568         }
  3511   3569         break;
         3570  +    }
         3571  +    case TK_SELECT_COLUMN: {
         3572  +      if( pExpr->pLeft->iTable==0 ){
         3573  +        pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0);
         3574  +      }
         3575  +      inReg = pExpr->pLeft->iTable + pExpr->iColumn;
         3576  +      break;
  3512   3577       }
  3513   3578       case TK_IN: {
  3514   3579         int destIfFalse = sqlite3VdbeMakeLabel(v);
  3515   3580         int destIfNull = sqlite3VdbeMakeLabel(v);
  3516   3581         sqlite3VdbeAddOp2(v, OP_Null, 0, target);
  3517   3582         sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
  3518   3583         sqlite3VdbeAddOp2(v, OP_Integer, 1, target);

Changes to src/sqliteInt.h.

  2294   2294   
  2295   2295   #if SQLITE_MAX_EXPR_DEPTH>0
  2296   2296     int nHeight;           /* Height of the tree headed by this node */
  2297   2297   #endif
  2298   2298     int iTable;            /* TK_COLUMN: cursor number of table holding column
  2299   2299                            ** TK_REGISTER: register number
  2300   2300                            ** TK_TRIGGER: 1 -> new, 0 -> old
  2301         -                         ** EP_Unlikely:  134217728 times likelihood */
         2301  +                         ** EP_Unlikely:  134217728 times likelihood
         2302  +                         ** TK_SELECT: 1st register of result vector */
  2302   2303     ynVar iColumn;         /* TK_COLUMN: column index.  -1 for rowid.
  2303         -                         ** TK_VARIABLE: variable number (always >= 1). */
         2304  +                         ** TK_VARIABLE: variable number (always >= 1).
         2305  +                         ** TK_SELECT_COLUMN: column of the result vector */
  2304   2306     i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  2305   2307     i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  2306   2308     u8 op2;                /* TK_REGISTER: original value of Expr.op
  2307   2309                            ** TK_COLUMN: the value of p5 for OP_Column
  2308   2310                            ** TK_AGG_FUNCTION: nesting depth */
  2309   2311     AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  2310   2312     Table *pTab;           /* Table for TK_COLUMN expressions. */
................................................................................
  4269   4271   
  4270   4272   #if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
  4271   4273   int sqlite3DbstatRegister(sqlite3*);
  4272   4274   #endif
  4273   4275   
  4274   4276   int sqlite3ExprVectorSize(Expr *pExpr);
  4275   4277   int sqlite3ExprIsVector(Expr *pExpr);
  4276         -Expr *sqlite3ExprVectorField(Expr*, int);
         4278  +Expr *sqlite3VectorFieldSubexpr(Expr*, int);
         4279  +Expr *sqlite3ExprForVectorField(Parse*,Expr*,int,int);
  4277   4280   
  4278   4281   #endif /* SQLITEINT_H */

Changes to src/vdbemem.c.

  1567   1567   
  1568   1568       alloc.pParse = pParse;
  1569   1569       alloc.pIdx = pIdx;
  1570   1570       alloc.ppRec = ppRec;
  1571   1571   
  1572   1572       for(i=0; i<nElem; i++){
  1573   1573         sqlite3_value *pVal = 0;
  1574         -      Expr *pElem = (pExpr ? sqlite3ExprVectorField(pExpr, i) : 0);
         1574  +      Expr *pElem = (pExpr ? sqlite3VectorFieldSubexpr(pExpr, i) : 0);
  1575   1575         u8 aff = sqlite3IndexColumnAffinity(pParse->db, pIdx, iVal+i);
  1576   1576         alloc.iVal = iVal+i;
  1577   1577         rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc, &pVal);
  1578   1578         if( !pVal ) break;
  1579   1579         nExtract++;
  1580   1580       }
  1581   1581     }

Changes to src/wherecode.c.

   373    373     Expr *pX = pTerm->pExpr;
   374    374     Vdbe *v = pParse->pVdbe;
   375    375     int iReg;                  /* Register holding results */
   376    376   
   377    377     assert( pLevel->pWLoop->aLTerm[iEq]==pTerm );
   378    378     assert( iTarget>0 );
   379    379     if( pX->op==TK_EQ || pX->op==TK_IS ){
   380         -    Expr *pRight = pX->pRight;
   381         -#ifndef SQLITE_OMIT_SUBQUERY
   382         -    if( pRight->op==TK_SELECT_COLUMN ){
   383         -      /* This case occurs for expressions like "(a, b) == (SELECT ...)". */
   384         -      WhereLoop *pLoop = pLevel->pWLoop;
   385         -      int i;
   386         -      Expr *pSub = pRight->pLeft;
   387         -      assert( pSub->op==TK_SELECT );
   388         -      for(i=pLoop->nSkip; i<iEq; i++){
   389         -        Expr *pExpr = pLoop->aLTerm[i]->pExpr->pRight;
   390         -        if( pExpr && pExpr->op==TK_SELECT_COLUMN && pExpr->pLeft==pSub ) break;
   391         -      }
   392         -
   393         -      if( i==iEq ){
   394         -        iReg = sqlite3CodeSubselect(pParse, pSub, 0, 0);
   395         -        for(/*no-op*/; i<pLoop->nLTerm; i++){
   396         -          Expr *pExpr = pLoop->aLTerm[i]->pExpr->pRight;
   397         -          if( pExpr && pExpr->op==TK_SELECT_COLUMN && pExpr->pLeft==pSub ){
   398         -            sqlite3VdbeAddOp2(v, OP_Copy, iReg+pExpr->iColumn, iTarget-iEq+i);
   399         -          }
   400         -        }
   401         -      }
   402         -      iReg = iTarget;
   403         -    }else
   404         -#endif
   405         -    {
   406         -      iReg = sqlite3ExprCodeTarget(pParse, pRight, iTarget);
   407         -    }
          380  +    iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
   408    381     }else if( pX->op==TK_ISNULL ){
   409    382       iReg = iTarget;
   410    383       sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
   411    384   #ifndef SQLITE_OMIT_SUBQUERY
   412    385     }else{
   413    386       int eType;
   414    387       int iTab;
................................................................................
  1097   1070         pTerm = pLoop->aLTerm[j];
  1098   1071         if( NEVER(pTerm==0) ) continue;
  1099   1072         if( pTerm->eOperator & WO_IN ){
  1100   1073           codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
  1101   1074           addrNotFound = pLevel->addrNxt;
  1102   1075         }else{
  1103   1076           Expr *pRight = pTerm->pExpr->pRight;
  1104         -        if( pRight->op==TK_SELECT_COLUMN ){
  1105         -          codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
  1106         -        }else{
  1107         -          codeExprOrVector(pParse, pRight, iTarget, 1);
  1108         -        }
         1077  +        codeExprOrVector(pParse, pRight, iTarget, 1);
  1109   1078         }
  1110   1079       }
  1111   1080       sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
  1112   1081       sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
  1113   1082       sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
  1114   1083                         pLoop->u.vtab.idxStr,
  1115   1084                         pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC);

Changes to src/whereexpr.c.

   869    869           return 1;
   870    870         }
   871    871       }
   872    872     }
   873    873     return 0;
   874    874   }
   875    875   
   876         -/*
   877         -** The expression passed as the second argument is a vector (either a 
   878         -** TK_VECTOR node or a TK_SELECT that returns more than one column). This
   879         -** function returns a pointer to a new expression object representing
   880         -** field iField of the vector.
   881         -**
   882         -** If pVector is of type TK_VECTOR, the returned object is just a copy of
   883         -** the iField'th element of the vector. Or, if pVector is of type TK_SELECT,
   884         -** the return value points to a new expression object of type 
   885         -** TK_SELECT_COLUMN.
   886         -*/
   887         -static Expr *exprExtractVectorField(Parse *pParse, Expr *pVector, int iField){
   888         -  Expr *pRet;
   889         -  assert( sqlite3ExprIsVector(pVector) );
   890         -  if( pVector->flags & EP_xIsSelect ){
   891         -    pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, pVector, 0, 0);
   892         -    if( pRet ) pRet->iColumn = iField;
   893         -  }else{
   894         -    pRet = sqlite3ExprDup(pParse->db, pVector->x.pList->a[iField].pExpr, 0);
   895         -  }
   896         -  return pRet;
   897         -}
   898         -
   899    876   /*
   900    877   ** The input to this routine is an WhereTerm structure with only the
   901    878   ** "pExpr" field filled in.  The job of this routine is to analyze the
   902    879   ** subexpression and populate all the other fields of the WhereTerm
   903    880   ** structure.
   904    881   **
   905    882   ** If the expression is of the form "<expr> <op> X" it gets commuted
................................................................................
  1207   1184     )){
  1208   1185       int nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
  1209   1186       if( nLeft==sqlite3ExprVectorSize(pExpr->pRight) ){
  1210   1187         int i;
  1211   1188         for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
  1212   1189           int idxNew;
  1213   1190           Expr *pNew;
  1214         -        Expr *pLeft = exprExtractVectorField(pParse, pExpr->pLeft, i);
  1215         -        Expr *pRight = exprExtractVectorField(pParse, pExpr->pRight, i);
         1191  +        Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i, 0);
         1192  +        Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i, 0);
  1216   1193   
  1217   1194           pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0);
  1218         -        idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
         1195  +        idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
  1219   1196           exprAnalyze(pSrc, pWC, idxNew);
  1220   1197           markTermAsChild(pWC, idxNew, idxTerm);
  1221   1198         }
         1199  +      pTerm = &pWC->a[idxTerm];
         1200  +      pTerm->wtFlags = TERM_CODED;
         1201  +      pTerm->eOperator = 0;
  1222   1202       }
  1223   1203     }
  1224   1204   
  1225   1205     /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
  1226   1206     ** a virtual term for each vector component. The expression object
  1227   1207     ** used by each such virtual term is pExpr (the full vector IN(...) 
  1228   1208     ** expression). The WhereTerm.iField variable identifies the index within