SQLite

Check-in [a3ffd283bc]
Login

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

Overview
Comment:Improvements to the vector comparison splitter in exprAnalyze().
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | rowvalue
Files: files | file ages | folders
SHA1: a3ffd283bc931b04170ef737e56bced33d27f06d
User & Date: drh 2016-08-20 12:00:05.657
Context
2016-08-20
15:01
Fix a segfault that could occur if a query that used a vector comparison contained certain types of syntax errors. (check-in: 203f07c5e1 user: dan tags: rowvalue)
12:00
Improvements to the vector comparison splitter in exprAnalyze(). (check-in: a3ffd283bc user: drh tags: rowvalue)
01:06
Improvements to comments. No code changes. (check-in: 4165d20f64 user: drh tags: rowvalue)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/whereexpr.c.
1169
1170
1171
1172
1173
1174
1175
1176



1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
      pTerm->wtFlags |= TERM_COPIED;
      pNewTerm->prereqAll = pTerm->prereqAll;
    }
  }
#endif /* SQLITE_OMIT_VIRTUALTABLE */

  /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create
  ** a virtual term for each component comparison - "a = ?" and "b = ?".



  ** This is only required if at least one side of the comparison operation
  ** is not a sub-select.  */
  if( pWC->op==TK_AND 
  && (pExpr->op==TK_EQ || pExpr->op==TK_IS)
  && sqlite3ExprIsVector(pExpr->pLeft)
  && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 
    || (pExpr->pRight->flags & EP_xIsSelect)==0
  )){
    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);
        Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i);

        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(...) 







|
>
>
>




















<


|







1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
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
1209
      pTerm->wtFlags |= TERM_COPIED;
      pNewTerm->prereqAll = pTerm->prereqAll;
    }
  }
#endif /* SQLITE_OMIT_VIRTUALTABLE */

  /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create
  ** new terms for each component comparison - "a = ?" and "b = ?".  The
  ** new terms completely replace the original vector comparison, which is
  ** no longer used.
  **
  ** This is only required if at least one side of the comparison operation
  ** is not a sub-select.  */
  if( pWC->op==TK_AND 
  && (pExpr->op==TK_EQ || pExpr->op==TK_IS)
  && sqlite3ExprIsVector(pExpr->pLeft)
  && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 
    || (pExpr->pRight->flags & EP_xIsSelect)==0
  )){
    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);
        Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i);

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

      }
      pTerm = &pWC->a[idxTerm];
      pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL;  /* Disable the original */
      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(...)