SQLite

Check-in [cff1b36ab2]
Login

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

Overview
Comment:Suppress excess OP_Null opcodes caused by binary IS or IS NOT operators that are converted into unary ISNULL or NOTNULL operators.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: cff1b36ab2c417611f59e96694005c03762788d2
User & Date: drh 2009-11-12 03:46:34.000
Context
2009-11-12
04:26
Suppress unnecessary OP_Noop instructions on when the right table of a LEFT JOIN uses the index-only optimization. (check-in: e8aec08bee user: drh tags: trunk)
03:46
Suppress excess OP_Null opcodes caused by binary IS or IS NOT operators that are converted into unary ISNULL or NOTNULL operators. (check-in: cff1b36ab2 user: drh tags: trunk)
03:13
Adjustments to the implementation of LIMIT so that it uses fewer opcodes. (check-in: 39d5b292d2 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/parse.y.
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
906
907
908
909
910
    pOut->zStart = pOperand->zStart;
    pOut->zEnd = &pPostOp->z[pPostOp->n];
  }                           
}

expr(A) ::= expr(X) ISNULL|NOTNULL(E).   {spanUnaryPostfix(&A,pParse,@E,&X,&E);}
expr(A) ::= expr(X) NOT NULL(E). {spanUnaryPostfix(&A,pParse,TK_NOTNULL,&X,&E);}














//    expr1 IS expr2
//    expr1 IS NOT expr2
//
// If expr2 is NULL then code as TK_ISNULL or TK_NOTNULL.  If expr2
// is any other expression, code as TK_IS or TK_ISNOT.
// 
expr(A) ::= expr(X) IS expr(Y).     {
  spanBinaryExpr(&A,pParse,TK_IS,&X,&Y);
  if( pParse->db->mallocFailed==0  && Y.pExpr->op==TK_NULL ){
    A.pExpr->op = TK_ISNULL;
  }
}
expr(A) ::= expr(X) IS NOT expr(Y). {
  spanBinaryExpr(&A,pParse,TK_ISNOT,&X,&Y);
  if( pParse->db->mallocFailed==0  && Y.pExpr->op==TK_NULL ){
    A.pExpr->op = TK_NOTNULL;
  }
}

%include {
  /* Construct an expression node for a unary prefix operator
  */
  static void spanUnaryPrefix(
    ExprSpan *pOut,        /* Write the new expression node here */







>
>
>
>
>
>
>
>
>
>
>
>
>









<
|
<



<
|
<







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
906
907

908

909
910
911

912

913
914
915
916
917
918
919
    pOut->zStart = pOperand->zStart;
    pOut->zEnd = &pPostOp->z[pPostOp->n];
  }                           
}

expr(A) ::= expr(X) ISNULL|NOTNULL(E).   {spanUnaryPostfix(&A,pParse,@E,&X,&E);}
expr(A) ::= expr(X) NOT NULL(E). {spanUnaryPostfix(&A,pParse,TK_NOTNULL,&X,&E);}

%include {
  /* A routine to convert a binary TK_IS or TK_ISNOT expression into a
  ** unary TK_ISNULL or TK_NOTNULL expression. */
  static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
    sqlite3 *db = pParse->db;
    if( db->mallocFailed==0 && pY->op==TK_NULL ){
      pA->op = op;
      sqlite3ExprDelete(db, pA->pRight);
      pA->pRight = 0;
    }
  }
}

//    expr1 IS expr2
//    expr1 IS NOT expr2
//
// If expr2 is NULL then code as TK_ISNULL or TK_NOTNULL.  If expr2
// is any other expression, code as TK_IS or TK_ISNOT.
// 
expr(A) ::= expr(X) IS expr(Y).     {
  spanBinaryExpr(&A,pParse,TK_IS,&X,&Y);

  binaryToUnaryIfNull(pParse, Y.pExpr, A.pExpr, TK_ISNULL);

}
expr(A) ::= expr(X) IS NOT expr(Y). {
  spanBinaryExpr(&A,pParse,TK_ISNOT,&X,&Y);

  binaryToUnaryIfNull(pParse, Y.pExpr, A.pExpr, TK_NOTNULL);

}

%include {
  /* Construct an expression node for a unary prefix operator
  */
  static void spanUnaryPrefix(
    ExprSpan *pOut,        /* Write the new expression node here */