/ Check-in [8b4c3c5e]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:An optimization that converts "a IN (b)" into "a==b". Seems to work, but needs additional test cases.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | degenerate_IN
Files: files | file ages | folders
SHA1: 8b4c3c5e506267c18550063cb9bd93519c871b0e
User & Date: drh 2012-10-16 21:08:03
Context
2012-10-16
21:08
An optimization that converts "a IN (b)" into "a==b". Seems to work, but needs additional test cases. Leaf check-in: 8b4c3c5e user: drh tags: degenerate_IN
2012-10-15
20:28
Correct comments and enhance readability of the mkvsix tool. check-in: 2c3af657 user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/parse.y.

   994    994     A.zEnd = Y.zEnd;
   995    995   }
   996    996   %ifndef SQLITE_OMIT_SUBQUERY
   997    997     %type in_op {int}
   998    998     in_op(A) ::= IN.      {A = 0;}
   999    999     in_op(A) ::= NOT IN.  {A = 1;}
  1000   1000     expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] {
  1001         -    if( Y==0 ){
         1001  +    sqlite3 *db = pParse->db;
         1002  +    ExprList *pY = Y;
         1003  +    if( pY==0 ){
  1002   1004         /* Expressions of the form
  1003   1005         **
  1004   1006         **      expr1 IN ()
  1005   1007         **      expr1 NOT IN ()
  1006   1008         **
  1007   1009         ** simplify to constants 0 (false) and 1 (true), respectively,
  1008   1010         ** regardless of the value of expr1.
  1009   1011         */
  1010   1012         A.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[N]);
  1011         -      sqlite3ExprDelete(pParse->db, X.pExpr);
         1013  +      sqlite3ExprDelete(db, X.pExpr);
         1014  +    }else if( pY->nExpr==1 ){
         1015  +      /* If the RHS of the IN operator has a single term, simplify as follows:
         1016  +      **
         1017  +      **      expr1 IN (Y)        -->      expr1 = Y
         1018  +      **      expr1 NOT IN (Y)    -->      expr1 <> Y
         1019  +      */
         1020  +      assert( TK_EQ==TK_NE+1 );
         1021  +      A.pExpr = sqlite3PExpr(pParse, TK_EQ-N, X.pExpr, pY->a[0].pExpr, 0);
         1022  +      pY->a[0].pExpr = 0;
         1023  +      sqlite3ExprListDelete(db, pY);
  1012   1024       }else{
  1013   1025         A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
  1014   1026         if( A.pExpr ){
  1015         -        A.pExpr->x.pList = Y;
         1027  +        A.pExpr->x.pList = pY;
  1016   1028           sqlite3ExprSetHeight(pParse, A.pExpr);
  1017   1029         }else{
  1018         -        sqlite3ExprListDelete(pParse->db, Y);
         1030  +        sqlite3ExprListDelete(pParse->db, pY);
  1019   1031         }
  1020   1032         if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
  1021   1033       }
  1022   1034       A.zStart = X.zStart;
  1023   1035       A.zEnd = &E.z[E.n];
  1024   1036     }
  1025   1037     expr(A) ::= LP(B) select(X) RP(E). {