/ 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 Unified Diffs Show Whitespace Changes Patch

Changes to src/expr.c.

330
331
332
333
334
335
336
337
338
339
340
341








342
343
344
345
346
347
348
349
350
351
352
353
354


















































355
356
357
358
359
360
361
....
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
....
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
....
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
....
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
....
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
....
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
....
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
....
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
....
3505
3506
3507
3508
3509
3510
3511







3512
3513
3514
3515
3516
3517
3518
    return pExpr->x.pSelect->pEList->nExpr;
  }
  return pExpr->x.pList->nExpr;
}

#ifndef SQLITE_OMIT_SUBQUERY
/*
** If the expression passed as the first argument is a TK_VECTOR, return
** a pointer to the i'th field of the vector. Or, if the first argument
** points to a sub-select that returns more than one column, return a 
** pointer to the i'th returned column value. Otherwise, return a copy 
** of the first argument.








*/
Expr *sqlite3ExprVectorField(Expr *pVector, int i){
  assert( i<sqlite3ExprVectorSize(pVector) );
  if( sqlite3ExprIsVector(pVector) ){
    if( pVector->op==TK_SELECT ){
      return pVector->x.pSelect->pEList->a[i].pExpr;
    }else{
      return pVector->x.pList->a[i].pExpr;
    }
  }
  return pVector;
}
#endif



















































/*
** If expression pExpr is of type TK_SELECT, generate code to evaluate
** it. Return the register in which the result is stored (or, if the 
** sub-select returns more than one column, the first in an array
** of registers in which the result is stored).
**
................................................................................
      int affinity_ok = 1;
      int i;

      /* Check that the affinity that will be used to perform each 
      ** comparison is the same as the affinity of each column. If
      ** it not, it is not possible to use any index.  */
      for(i=0; i<nExpr && affinity_ok; i++){
        Expr *pLhs = sqlite3ExprVectorField(pX->pLeft, i);
        int iCol = pEList->a[i].pExpr->iColumn;
        char idxaff = pTab->aCol[iCol].affinity;
        char cmpaff = sqlite3CompareAffinity(pLhs, idxaff);
        switch( cmpaff ){
          case SQLITE_AFF_BLOB:
            break;
          case SQLITE_AFF_TEXT:
................................................................................
      for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
        if( pIdx->nKeyCol<nExpr ) continue;
        if( mustBeUnique && (pIdx->nKeyCol!=nExpr || !IsUniqueIndex(pIdx)) ){
          continue;
        }

        for(i=0; i<nExpr; i++){
          Expr *pLhs = sqlite3ExprVectorField(pX->pLeft, i);
          Expr *pRhs = pEList->a[i].pExpr;
          CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
          int j;

          assert( pReq || pParse->nErr );
          if( pReq==0 ) break;

................................................................................
  char *zRet;

  assert( pExpr->op==TK_IN );
  zRet = sqlite3DbMallocZero(pParse->db, nVal+1);
  if( zRet ){
    int i;
    for(i=0; i<nVal; i++){
      Expr *pA = sqlite3ExprVectorField(pLeft, i);
      char a = sqlite3ExprAffinity(pA);
      if( pSelect ){
        zRet[i] = sqlite3CompareAffinity(pSelect->pEList->a[i].pExpr, a);
      }else{
        zRet[i] = a;
      }
    }
................................................................................
          }
          sqlite3DbFree(pParse->db, dest.zAffSdst);
          assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
          assert( pEList!=0 );
          assert( pEList->nExpr>0 );
          assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
          for(i=0; i<nVal; i++){
            Expr *p = (nVal>1) ? sqlite3ExprVectorField(pLeft, i) : pLeft;
            pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
                pParse, p, pEList->a[i].pExpr
            );
          }
        }
      }else if( ALWAYS(pExpr->x.pList!=0) ){
        /* Case 2:     expr IN (exprlist)
................................................................................
  if( nVector>1 && (pLeft->flags & EP_xIsSelect) ){
    int regSelect = sqlite3CodeSubselect(pParse, pLeft, 0, 0);
    for(i=0; i<nVector; i++){
      sqlite3VdbeAddOp3(v, OP_Copy, regSelect+i, r1+aiMap[i], 0);
    }
  }else{
    for(i=0; i<nVector; i++){
      Expr *pLhs = sqlite3ExprVectorField(pLeft, i);
      sqlite3ExprCode(pParse, pLhs, r1+aiMap[i]);
    }
  }

  /* If sqlite3FindInIndex() did not find or create an index that is
  ** suitable for evaluating the IN operator, then evaluate using a
  ** sequence of comparisons.
................................................................................
    **
    ** Otherwise, if NULL and false are handled differently, and the
    ** IN(...) operation is not a vector operation, and the LHS of the
    ** operator is NULL, then the result is false if the index is 
    ** completely empty, or NULL otherwise.  */
    if( destIfNull==destIfFalse ){
      for(i=0; i<nVector; i++){
        Expr *p = sqlite3ExprVectorField(pExpr->pLeft, i);
        if( sqlite3ExprCanBeNull(p) ){
          sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull);
          VdbeCoverage(v);
        }
      }
    }else if( nVector==1 && sqlite3ExprCanBeNull(pExpr->pLeft) ){
      int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v);
................................................................................
        addrNext = 1+sqlite3VdbeAddOp2(v, OP_Rewind, iIdx, destIfFalse);
        VdbeCoverage(v);

        for(i=0; i<nVector; i++){
          Expr *p;
          CollSeq *pColl;
          int r2 = sqlite3GetTempReg(pParse);
          p = sqlite3ExprVectorField(pLeft, i);
          pColl = sqlite3ExprCollSeq(pParse, p);

          sqlite3VdbeAddOp3(v, OP_Column, iIdx, i, r2);
          sqlite3VdbeAddOp4(v, OP_Eq, r1+i, 0, r2, (void*)pColl,P4_COLLSEQ);
          sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
          VdbeCoverage(v);
          sqlite3VdbeAddOp2(v, OP_Next, iIdx, addrNext);
................................................................................
        sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);

        /* The key was found in the index. If it contains any NULL values,
        ** then the result of the IN(...) operator is NULL. Otherwise, the
        ** result is 1.  */
        sqlite3VdbeJumpHere(v, addr);
        for(i=0; i<nVector; i++){
          Expr *p = sqlite3ExprVectorField(pExpr->pLeft, i);
          if( sqlite3ExprCanBeNull(p) ){
            sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull);
            VdbeCoverage(v);
          }
        }

      }else if( rRhsHasNull==0 ){
................................................................................
      testcase( op==TK_SELECT );
      if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
        sqlite3SubselectError(pParse, nCol, 1);
      }else{
        inReg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
      }
      break;







    }
    case TK_IN: {
      int destIfFalse = sqlite3VdbeMakeLabel(v);
      int destIfNull = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp2(v, OP_Null, 0, target);
      sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
      sqlite3VdbeAddOp2(v, OP_Integer, 1, target);







|
|
|
|
|
>
>
>
>
>
>
>
>

|










|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







>
>
>
>
>
>
>







330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
....
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
....
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
....
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
....
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
....
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
....
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
....
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
....
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
....
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
    return pExpr->x.pSelect->pEList->nExpr;
  }
  return pExpr->x.pList->nExpr;
}

#ifndef SQLITE_OMIT_SUBQUERY
/*
** Interpret the pVector input as a vector expression.  If pVector is
** an ordinary scalar expression, treat it as a vector of size 1.
**
** Return a pointer to a subexpression of pVector that is the i-th
** column of the vector (numbered starting with 0).  The caller must
** ensure that i is within range.
**
** pVector retains ownership of the returned subexpression.
**
** If the vector is a (SELECT ...) then the expression returned is
** just the expression for the i-th term of the result set, and is
** necessarily ready to be evaluated because the table cursor might
** not have been positioned yet.
*/
Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
  assert( i<sqlite3ExprVectorSize(pVector) );
  if( sqlite3ExprIsVector(pVector) ){
    if( pVector->op==TK_SELECT ){
      return pVector->x.pSelect->pEList->a[i].pExpr;
    }else{
      return pVector->x.pList->a[i].pExpr;
    }
  }
  return pVector;
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) */

#ifndef SQLITE_OMIT_SUBQUERY
/*
** Compute and return a new Expr object which when passed to
** sqlite3ExprCode() will generate all necessary code to compute
** the iField-th column of the vector expression pVector.
**
** The caller owns the returned Expr object and is responsible for
** ensuring that the returned value eventually gets freed.
**
** Ownership of pVector is controlled by the takeOwnership parameter.  If
** takeOwnership is true, this routine takes responsibility for freeing
** pVector, and may do so before returning, hence the caller must not reference
** pVector again.  If takeOwnership is false, then the caller takes
** responsibility for freeing pVector and must ensure the pVector remains
** valid as long as the returned value remains in use.
*/
Expr *sqlite3ExprForVectorField(
  Parse *pParse,       /* Parsing context */
  Expr *pVector,       /* The vector.  List of expressions or a sub-SELECT */
  int iField,          /* Which column of the vector to return */
  int takeOwnership    /* True to take ownership of pVector before returning */
){
  Expr *pRet;
  assert( sqlite3ExprIsVector(pVector) );
  /* FIXME: Add support for takeOwnership!=0 */ assert( takeOwnership==0 );
  if( pVector->flags & EP_xIsSelect ){
    /* The TK_SELECT_COLUMN Expr node:
    **
    ** pLeft:           pVector containing TK_SELECT
    ** pRight:          pVector if ownership taken
    ** iColumn:         Index of a column in pVector
    ** pLeft->iTable:   First in an array of register holding result, or 0
    **                  if the result is not yet computed.
    **
    ** sqlite3ExprDelete() specifically skips the recursive delete of
    ** pLeft on TK_SELECT_COLUMN nodes.  But pRight is followed, so pVector
    ** is included on pRight if ownership is taken.  Typically there will
    ** be multiple TK_SELECT_COLUMN nodes with the same pLeft pointer to 
    ** the pVector, but only one of them will own the pVector.
    */
    pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, pVector, 0, 0);
    if( pRet ) pRet->iColumn = iField;
    assert( pRet==0 || pRet->iTable==0 );
  }else{
    pRet = sqlite3ExprDup(pParse->db, pVector->x.pList->a[iField].pExpr, 0);
  }
  return pRet;
}
#endif /* !define(SQLITE_OMIT_SUBQUERY) */

/*
** If expression pExpr is of type TK_SELECT, generate code to evaluate
** it. Return the register in which the result is stored (or, if the 
** sub-select returns more than one column, the first in an array
** of registers in which the result is stored).
**
................................................................................
      int affinity_ok = 1;
      int i;

      /* Check that the affinity that will be used to perform each 
      ** comparison is the same as the affinity of each column. If
      ** it not, it is not possible to use any index.  */
      for(i=0; i<nExpr && affinity_ok; i++){
        Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
        int iCol = pEList->a[i].pExpr->iColumn;
        char idxaff = pTab->aCol[iCol].affinity;
        char cmpaff = sqlite3CompareAffinity(pLhs, idxaff);
        switch( cmpaff ){
          case SQLITE_AFF_BLOB:
            break;
          case SQLITE_AFF_TEXT:
................................................................................
      for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
        if( pIdx->nKeyCol<nExpr ) continue;
        if( mustBeUnique && (pIdx->nKeyCol!=nExpr || !IsUniqueIndex(pIdx)) ){
          continue;
        }

        for(i=0; i<nExpr; i++){
          Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
          Expr *pRhs = pEList->a[i].pExpr;
          CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
          int j;

          assert( pReq || pParse->nErr );
          if( pReq==0 ) break;

................................................................................
  char *zRet;

  assert( pExpr->op==TK_IN );
  zRet = sqlite3DbMallocZero(pParse->db, nVal+1);
  if( zRet ){
    int i;
    for(i=0; i<nVal; i++){
      Expr *pA = sqlite3VectorFieldSubexpr(pLeft, i);
      char a = sqlite3ExprAffinity(pA);
      if( pSelect ){
        zRet[i] = sqlite3CompareAffinity(pSelect->pEList->a[i].pExpr, a);
      }else{
        zRet[i] = a;
      }
    }
................................................................................
          }
          sqlite3DbFree(pParse->db, dest.zAffSdst);
          assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
          assert( pEList!=0 );
          assert( pEList->nExpr>0 );
          assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
          for(i=0; i<nVal; i++){
            Expr *p = (nVal>1) ? sqlite3VectorFieldSubexpr(pLeft, i) : pLeft;
            pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
                pParse, p, pEList->a[i].pExpr
            );
          }
        }
      }else if( ALWAYS(pExpr->x.pList!=0) ){
        /* Case 2:     expr IN (exprlist)
................................................................................
  if( nVector>1 && (pLeft->flags & EP_xIsSelect) ){
    int regSelect = sqlite3CodeSubselect(pParse, pLeft, 0, 0);
    for(i=0; i<nVector; i++){
      sqlite3VdbeAddOp3(v, OP_Copy, regSelect+i, r1+aiMap[i], 0);
    }
  }else{
    for(i=0; i<nVector; i++){
      Expr *pLhs = sqlite3VectorFieldSubexpr(pLeft, i);
      sqlite3ExprCode(pParse, pLhs, r1+aiMap[i]);
    }
  }

  /* If sqlite3FindInIndex() did not find or create an index that is
  ** suitable for evaluating the IN operator, then evaluate using a
  ** sequence of comparisons.
................................................................................
    **
    ** Otherwise, if NULL and false are handled differently, and the
    ** IN(...) operation is not a vector operation, and the LHS of the
    ** operator is NULL, then the result is false if the index is 
    ** completely empty, or NULL otherwise.  */
    if( destIfNull==destIfFalse ){
      for(i=0; i<nVector; i++){
        Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
        if( sqlite3ExprCanBeNull(p) ){
          sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull);
          VdbeCoverage(v);
        }
      }
    }else if( nVector==1 && sqlite3ExprCanBeNull(pExpr->pLeft) ){
      int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v);
................................................................................
        addrNext = 1+sqlite3VdbeAddOp2(v, OP_Rewind, iIdx, destIfFalse);
        VdbeCoverage(v);

        for(i=0; i<nVector; i++){
          Expr *p;
          CollSeq *pColl;
          int r2 = sqlite3GetTempReg(pParse);
          p = sqlite3VectorFieldSubexpr(pLeft, i);
          pColl = sqlite3ExprCollSeq(pParse, p);

          sqlite3VdbeAddOp3(v, OP_Column, iIdx, i, r2);
          sqlite3VdbeAddOp4(v, OP_Eq, r1+i, 0, r2, (void*)pColl,P4_COLLSEQ);
          sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
          VdbeCoverage(v);
          sqlite3VdbeAddOp2(v, OP_Next, iIdx, addrNext);
................................................................................
        sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);

        /* The key was found in the index. If it contains any NULL values,
        ** then the result of the IN(...) operator is NULL. Otherwise, the
        ** result is 1.  */
        sqlite3VdbeJumpHere(v, addr);
        for(i=0; i<nVector; i++){
          Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
          if( sqlite3ExprCanBeNull(p) ){
            sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull);
            VdbeCoverage(v);
          }
        }

      }else if( rRhsHasNull==0 ){
................................................................................
      testcase( op==TK_SELECT );
      if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
        sqlite3SubselectError(pParse, nCol, 1);
      }else{
        inReg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
      }
      break;
    }
    case TK_SELECT_COLUMN: {
      if( pExpr->pLeft->iTable==0 ){
        pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0);
      }
      inReg = pExpr->pLeft->iTable + pExpr->iColumn;
      break;
    }
    case TK_IN: {
      int destIfFalse = sqlite3VdbeMakeLabel(v);
      int destIfNull = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp2(v, OP_Null, 0, target);
      sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
      sqlite3VdbeAddOp2(v, OP_Integer, 1, target);

Changes to src/sqliteInt.h.

2294
2295
2296
2297
2298
2299
2300
2301

2302
2303

2304
2305
2306
2307
2308
2309
2310
....
4269
4270
4271
4272
4273
4274
4275

4276
4277
4278

#if SQLITE_MAX_EXPR_DEPTH>0
  int nHeight;           /* Height of the tree headed by this node */
#endif
  int iTable;            /* TK_COLUMN: cursor number of table holding column
                         ** TK_REGISTER: register number
                         ** TK_TRIGGER: 1 -> new, 0 -> old
                         ** EP_Unlikely:  134217728 times likelihood */

  ynVar iColumn;         /* TK_COLUMN: column index.  -1 for rowid.
                         ** TK_VARIABLE: variable number (always >= 1). */

  i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  u8 op2;                /* TK_REGISTER: original value of Expr.op
                         ** TK_COLUMN: the value of p5 for OP_Column
                         ** TK_AGG_FUNCTION: nesting depth */
  AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  Table *pTab;           /* Table for TK_COLUMN expressions. */
................................................................................

#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
int sqlite3DbstatRegister(sqlite3*);
#endif

int sqlite3ExprVectorSize(Expr *pExpr);
int sqlite3ExprIsVector(Expr *pExpr);

Expr *sqlite3ExprVectorField(Expr*, int);

#endif /* SQLITEINT_H */







|
>

|
>







 







>
|


2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
....
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281

#if SQLITE_MAX_EXPR_DEPTH>0
  int nHeight;           /* Height of the tree headed by this node */
#endif
  int iTable;            /* TK_COLUMN: cursor number of table holding column
                         ** TK_REGISTER: register number
                         ** TK_TRIGGER: 1 -> new, 0 -> old
                         ** EP_Unlikely:  134217728 times likelihood
                         ** TK_SELECT: 1st register of result vector */
  ynVar iColumn;         /* TK_COLUMN: column index.  -1 for rowid.
                         ** TK_VARIABLE: variable number (always >= 1).
                         ** TK_SELECT_COLUMN: column of the result vector */
  i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  u8 op2;                /* TK_REGISTER: original value of Expr.op
                         ** TK_COLUMN: the value of p5 for OP_Column
                         ** TK_AGG_FUNCTION: nesting depth */
  AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  Table *pTab;           /* Table for TK_COLUMN expressions. */
................................................................................

#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
int sqlite3DbstatRegister(sqlite3*);
#endif

int sqlite3ExprVectorSize(Expr *pExpr);
int sqlite3ExprIsVector(Expr *pExpr);
Expr *sqlite3VectorFieldSubexpr(Expr*, int);
Expr *sqlite3ExprForVectorField(Parse*,Expr*,int,int);

#endif /* SQLITEINT_H */

Changes to src/vdbemem.c.

1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581

    alloc.pParse = pParse;
    alloc.pIdx = pIdx;
    alloc.ppRec = ppRec;

    for(i=0; i<nElem; i++){
      sqlite3_value *pVal = 0;
      Expr *pElem = (pExpr ? sqlite3ExprVectorField(pExpr, i) : 0);
      u8 aff = sqlite3IndexColumnAffinity(pParse->db, pIdx, iVal+i);
      alloc.iVal = iVal+i;
      rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc, &pVal);
      if( !pVal ) break;
      nExtract++;
    }
  }







|







1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581

    alloc.pParse = pParse;
    alloc.pIdx = pIdx;
    alloc.ppRec = ppRec;

    for(i=0; i<nElem; i++){
      sqlite3_value *pVal = 0;
      Expr *pElem = (pExpr ? sqlite3VectorFieldSubexpr(pExpr, i) : 0);
      u8 aff = sqlite3IndexColumnAffinity(pParse->db, pIdx, iVal+i);
      alloc.iVal = iVal+i;
      rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc, &pVal);
      if( !pVal ) break;
      nExtract++;
    }
  }

Changes to src/wherecode.c.

373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
....
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
  Expr *pX = pTerm->pExpr;
  Vdbe *v = pParse->pVdbe;
  int iReg;                  /* Register holding results */

  assert( pLevel->pWLoop->aLTerm[iEq]==pTerm );
  assert( iTarget>0 );
  if( pX->op==TK_EQ || pX->op==TK_IS ){
    Expr *pRight = pX->pRight;
#ifndef SQLITE_OMIT_SUBQUERY
    if( pRight->op==TK_SELECT_COLUMN ){
      /* This case occurs for expressions like "(a, b) == (SELECT ...)". */
      WhereLoop *pLoop = pLevel->pWLoop;
      int i;
      Expr *pSub = pRight->pLeft;
      assert( pSub->op==TK_SELECT );
      for(i=pLoop->nSkip; i<iEq; i++){
        Expr *pExpr = pLoop->aLTerm[i]->pExpr->pRight;
        if( pExpr && pExpr->op==TK_SELECT_COLUMN && pExpr->pLeft==pSub ) break;
      }

      if( i==iEq ){
        iReg = sqlite3CodeSubselect(pParse, pSub, 0, 0);
        for(/*no-op*/; i<pLoop->nLTerm; i++){
          Expr *pExpr = pLoop->aLTerm[i]->pExpr->pRight;
          if( pExpr && pExpr->op==TK_SELECT_COLUMN && pExpr->pLeft==pSub ){
            sqlite3VdbeAddOp2(v, OP_Copy, iReg+pExpr->iColumn, iTarget-iEq+i);
          }
        }
      }
      iReg = iTarget;
    }else
#endif
    {
      iReg = sqlite3ExprCodeTarget(pParse, pRight, iTarget);
    }
  }else if( pX->op==TK_ISNULL ){
    iReg = iTarget;
    sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
#ifndef SQLITE_OMIT_SUBQUERY
  }else{
    int eType;
    int iTab;
................................................................................
      pTerm = pLoop->aLTerm[j];
      if( NEVER(pTerm==0) ) continue;
      if( pTerm->eOperator & WO_IN ){
        codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
        addrNotFound = pLevel->addrNxt;
      }else{
        Expr *pRight = pTerm->pExpr->pRight;
        if( pRight->op==TK_SELECT_COLUMN ){
          codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
        }else{
          codeExprOrVector(pParse, pRight, iTarget, 1);
        }
      }
    }
    sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
    sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
    sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
                      pLoop->u.vtab.idxStr,
                      pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC);
    VdbeCoverage(v);
    pLoop->u.vtab.needFree = 0;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<







 







<
<
<



<







373
374
375
376
377
378
379


























380

381
382
383
384
385
386
387
....
1070
1071
1072
1073
1074
1075
1076



1077
1078
1079

1080
1081
1082
1083
1084
1085
1086
  Expr *pX = pTerm->pExpr;
  Vdbe *v = pParse->pVdbe;
  int iReg;                  /* Register holding results */

  assert( pLevel->pWLoop->aLTerm[iEq]==pTerm );
  assert( iTarget>0 );
  if( pX->op==TK_EQ || pX->op==TK_IS ){


























    iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);

  }else if( pX->op==TK_ISNULL ){
    iReg = iTarget;
    sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
#ifndef SQLITE_OMIT_SUBQUERY
  }else{
    int eType;
    int iTab;
................................................................................
      pTerm = pLoop->aLTerm[j];
      if( NEVER(pTerm==0) ) continue;
      if( pTerm->eOperator & WO_IN ){
        codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
        addrNotFound = pLevel->addrNxt;
      }else{
        Expr *pRight = pTerm->pExpr->pRight;



        codeExprOrVector(pParse, pRight, iTarget, 1);
      }
    }

    sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
    sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
    sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
                      pLoop->u.vtab.idxStr,
                      pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC);
    VdbeCoverage(v);
    pLoop->u.vtab.needFree = 0;

Changes to src/whereexpr.c.

869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
....
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221



1222
1223
1224
1225
1226
1227
1228
        return 1;
      }
    }
  }
  return 0;
}

/*
** The expression passed as the second argument is a vector (either a 
** TK_VECTOR node or a TK_SELECT that returns more than one column). This
** function returns a pointer to a new expression object representing
** field iField of the vector.
**
** If pVector is of type TK_VECTOR, the returned object is just a copy of
** the iField'th element of the vector. Or, if pVector is of type TK_SELECT,
** the return value points to a new expression object of type 
** TK_SELECT_COLUMN.
*/
static Expr *exprExtractVectorField(Parse *pParse, Expr *pVector, int iField){
  Expr *pRet;
  assert( sqlite3ExprIsVector(pVector) );
  if( pVector->flags & EP_xIsSelect ){
    pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, pVector, 0, 0);
    if( pRet ) pRet->iColumn = iField;
  }else{
    pRet = sqlite3ExprDup(pParse->db, pVector->x.pList->a[iField].pExpr, 0);
  }
  return pRet;
}

/*
** The input to this routine is an WhereTerm structure with only the
** "pExpr" field filled in.  The job of this routine is to analyze the
** subexpression and populate all the other fields of the WhereTerm
** structure.
**
** If the expression is of the form "<expr> <op> X" it gets commuted
................................................................................
  )){
    int nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
    if( nLeft==sqlite3ExprVectorSize(pExpr->pRight) ){
      int i;
      for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
        int idxNew;
        Expr *pNew;
        Expr *pLeft = exprExtractVectorField(pParse, pExpr->pLeft, i);
        Expr *pRight = exprExtractVectorField(pParse, pExpr->pRight, i);

        pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0);
        idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
        exprAnalyze(pSrc, pWC, idxNew);
        markTermAsChild(pWC, idxNew, idxTerm);
      }



    }
  }

  /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
  ** a virtual term for each vector component. The expression object
  ** used by each such virtual term is pExpr (the full vector IN(...) 
  ** expression). The WhereTerm.iField variable identifies the index within







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|
|


|



>
>
>







869
870
871
872
873
874
875























876
877
878
879
880
881
882
....
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
        return 1;
      }
    }
  }
  return 0;
}
























/*
** The input to this routine is an WhereTerm structure with only the
** "pExpr" field filled in.  The job of this routine is to analyze the
** subexpression and populate all the other fields of the WhereTerm
** structure.
**
** If the expression is of the form "<expr> <op> X" it gets commuted
................................................................................
  )){
    int nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
    if( nLeft==sqlite3ExprVectorSize(pExpr->pRight) ){
      int i;
      for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
        int idxNew;
        Expr *pNew;
        Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i, 0);
        Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i, 0);

        pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0);
        idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
        exprAnalyze(pSrc, pWC, idxNew);
        markTermAsChild(pWC, idxNew, idxTerm);
      }
      pTerm = &pWC->a[idxTerm];
      pTerm->wtFlags = TERM_CODED;
      pTerm->eOperator = 0;
    }
  }

  /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
  ** a virtual term for each vector component. The expression object
  ** used by each such virtual term is pExpr (the full vector IN(...) 
  ** expression). The WhereTerm.iField variable identifies the index within