SQLite

Check-in [b3676377b2]
Login

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

Overview
Comment:More test cases. Remove some invalid testcase() macros. Rearrange some code for improved testability.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | index-is-operator
Files: files | file ages | folders
SHA1: b3676377b257bd8bb7fefe9c365d76cdc9e44856
User & Date: drh 2015-05-14 13:41:22.643
Context
2015-05-14
14:03
A few more test cases for the IS operator. (Closed-Leaf check-in: f397c8622a user: drh tags: index-is-operator)
13:41
More test cases. Remove some invalid testcase() macros. Rearrange some code for improved testability. (check-in: b3676377b2 user: drh tags: index-is-operator)
13:18
Add testcase() macros. Get transitive WHERE clause constraints on IS operators working again. (check-in: d195d4a65d user: drh tags: index-is-operator)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/where.c.
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
      testcase( j==1 );

      /* We have found a candidate table and column.  Check to see if that
      ** table and column is common to every term in the OR clause */
      okToChngToIN = 1;
      for(; i>=0 && okToChngToIN; i--, pOrTerm++){
        assert( pOrTerm->eOperator & WO_EQ );
        testcase( pOrTerm->pExpr->op==TK_IS );
        if( pOrTerm->leftCursor!=iCursor ){
          pOrTerm->wtFlags &= ~TERM_OR_OK;
        }else if( pOrTerm->u.leftColumn!=iColumn ){
          okToChngToIN = 0;
        }else{
          int affLeft, affRight;
          /* If the right-hand side is also a column, then the affinities







<







1116
1117
1118
1119
1120
1121
1122

1123
1124
1125
1126
1127
1128
1129
      testcase( j==1 );

      /* We have found a candidate table and column.  Check to see if that
      ** table and column is common to every term in the OR clause */
      okToChngToIN = 1;
      for(; i>=0 && okToChngToIN; i--, pOrTerm++){
        assert( pOrTerm->eOperator & WO_EQ );

        if( pOrTerm->leftCursor!=iCursor ){
          pOrTerm->wtFlags &= ~TERM_OR_OK;
        }else if( pOrTerm->u.leftColumn!=iColumn ){
          okToChngToIN = 0;
        }else{
          int affLeft, affRight;
          /* If the right-hand side is also a column, then the affinities
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
      Expr *pNew;            /* The complete IN operator */

      for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){
        if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
        assert( pOrTerm->eOperator & WO_EQ );
        assert( pOrTerm->leftCursor==iCursor );
        assert( pOrTerm->u.leftColumn==iColumn );
        testcase( pOrTerm->pExpr->op==TK_IS );
        pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
        pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup);
        pLeft = pOrTerm->pExpr->pLeft;
      }
      assert( pLeft!=0 );
      pDup = sqlite3ExprDup(db, pLeft, 0);
      pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0, 0);







<







1152
1153
1154
1155
1156
1157
1158

1159
1160
1161
1162
1163
1164
1165
      Expr *pNew;            /* The complete IN operator */

      for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){
        if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
        assert( pOrTerm->eOperator & WO_EQ );
        assert( pOrTerm->leftCursor==iCursor );
        assert( pOrTerm->u.leftColumn==iColumn );

        pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
        pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup);
        pLeft = pOrTerm->pExpr->pLeft;
      }
      assert( pLeft!=0 );
      pDup = sqlite3ExprDup(db, pLeft, 0);
      pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0, 0);
4105
4106
4107
4108
4109
4110
4111
4112
4113

4114
4115
4116
4117
4118
4119
4120
  ** then we cannot use the "t1.a=t2.b" constraint, but we can code
  ** the implied "t1.a=123" constraint.
  */
  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE, *pEAlt;
    WhereTerm *pAlt;
    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
    if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
    if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;

    if( pTerm->leftCursor!=iCur ) continue;
    if( pLevel->iLeftJoin ) continue;
    pE = pTerm->pExpr;
    assert( !ExprHasProperty(pE, EP_FromJoin) );
    assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
    pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady,
                    WO_EQ|WO_IN|WO_IS, 0);







<

>







4103
4104
4105
4106
4107
4108
4109

4110
4111
4112
4113
4114
4115
4116
4117
4118
  ** then we cannot use the "t1.a=t2.b" constraint, but we can code
  ** the implied "t1.a=123" constraint.
  */
  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE, *pEAlt;
    WhereTerm *pAlt;
    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;

    if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
    if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
    if( pTerm->leftCursor!=iCur ) continue;
    if( pLevel->iLeftJoin ) continue;
    pE = pTerm->pExpr;
    assert( !ExprHasProperty(pE, EP_FromJoin) );
    assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
    pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady,
                    WO_EQ|WO_IN|WO_IS, 0);
Changes to test/vtab1.test.
1081
1082
1083
1084
1085
1086
1087
1088






1089
1090
1091





1092
1093
1094
1095
1096
1097
1098
} {{} 15 16}
do_test vtab1.13-3 {
  execsql { 
    INSERT INTO c VALUES(15, NULL, 16);
    SELECT * FROM echo_c WHERE b IS NULL 
  }
} {15 {} 16}
do_test vtab1.13-3 {






  execsql { 
    SELECT * FROM echo_c WHERE b IS NULL AND a = 15;
  }





} {15 {} 16}


do_test vtab1-14.001 {
  execsql {SELECT rowid, * FROM echo_c WHERE +rowid IN (1,2,3)}
} {1 3 G H 2 {} 15 16 3 15 {} 16}
do_test vtab1-14.002 {







|
>
>
>
>
>
>



>
>
>
>
>







1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
} {{} 15 16}
do_test vtab1.13-3 {
  execsql { 
    INSERT INTO c VALUES(15, NULL, 16);
    SELECT * FROM echo_c WHERE b IS NULL 
  }
} {15 {} 16}
do_test vtab1.13-4 {
  unset -nocomplain null
  execsql { 
    SELECT * FROM echo_c WHERE b IS $null
  }
} {15 {} 16}
do_test vtab1.13-5 {
  execsql { 
    SELECT * FROM echo_c WHERE b IS NULL AND a = 15;
  }
} {15 {} 16}
do_test vtab1.13-6 {
  execsql { 
    SELECT * FROM echo_c WHERE NULL IS b AND a IS 15;
  }
} {15 {} 16}


do_test vtab1-14.001 {
  execsql {SELECT rowid, * FROM echo_c WHERE +rowid IN (1,2,3)}
} {1 3 G H 2 {} 15 16 3 15 {} 16}
do_test vtab1-14.002 {