SQLite

Check-in [057fb8b1]
Login

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

Overview
Comment:The expression "(X IS FALSE) BETWEEN FALSE AND TRUE" does not implie that X is not NULL. Ticket [fba33c8b1df6a915]
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 057fb8b1809b8b9c8fff0fd0804153b9644f0545c23c6ddc4758bda3381094b9
User & Date: drh 2019-08-30 15:11:08
Context
2019-08-30
16:00
The expression "(X IS FALSE) IN (FALSE)" does not imply that X is NOT NULL. Ticket [f8f472cbc77ba9c9] (check-in: dd661348 user: drh tags: trunk)
15:11
The expression "(X IS FALSE) BETWEEN FALSE AND TRUE" does not implie that X is not NULL. Ticket [fba33c8b1df6a915] (check-in: 057fb8b1 user: drh tags: trunk)
13:07
The expression "(x IS FALSE) IS FALSE" does not imply that X is not NULL. Ticket [a6408d42b9f44462] (check-in: 45ff2b1f user: drh tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

4970
4971
4972
4973
4974
4975
4976



4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
             sqlite3ExprSkipCollateAndLikely(pA),
             sqlite3ExprSkipCollateAndLikely(pB),
             iTab);
}

/*
** Return non-zero if Expr p can only be true if pNN is not NULL.



*/
static int exprImpliesNotNull(
  Parse *pParse,      /* Parsing context */
  Expr *p,            /* The expression to be checked */
  Expr *pNN,          /* The expression that is NOT NULL */
  int iTab,           /* Table being evaluated */
  int seenNot         /* True if p is an operand of NOT */
){
  assert( p );
  assert( pNN );
  if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ){
    return pNN->op!=TK_NULL;
  }
  switch( p->op ){
    case TK_IN: {
      if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
      assert( ExprHasProperty(p,EP_xIsSelect)
           || (p->x.pList!=0 && p->x.pList->nExpr>0) );
      return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
    }
    case TK_BETWEEN: {
      ExprList *pList = p->x.pList;
      assert( pList!=0 );
      assert( pList->nExpr==2 );
      if( seenNot ) return 0;
      if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, seenNot)
       || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, seenNot)
      ){
        return 1;
      }
      return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
    }
    case TK_EQ:
    case TK_NE:
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:







>
>
>






|


















|
|



|







4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
             sqlite3ExprSkipCollateAndLikely(pA),
             sqlite3ExprSkipCollateAndLikely(pB),
             iTab);
}

/*
** Return non-zero if Expr p can only be true if pNN is not NULL.
**
** Or if seenNot is true, return non-zero if Expr p can only be
** non-NULL if pNN is not NULL
*/
static int exprImpliesNotNull(
  Parse *pParse,      /* Parsing context */
  Expr *p,            /* The expression to be checked */
  Expr *pNN,          /* The expression that is NOT NULL */
  int iTab,           /* Table being evaluated */
  int seenNot         /* Return true only if p can be any non-NULL value */
){
  assert( p );
  assert( pNN );
  if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ){
    return pNN->op!=TK_NULL;
  }
  switch( p->op ){
    case TK_IN: {
      if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
      assert( ExprHasProperty(p,EP_xIsSelect)
           || (p->x.pList!=0 && p->x.pList->nExpr>0) );
      return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
    }
    case TK_BETWEEN: {
      ExprList *pList = p->x.pList;
      assert( pList!=0 );
      assert( pList->nExpr==2 );
      if( seenNot ) return 0;
      if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, 1)
       || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, 1)
      ){
        return 1;
      }
      return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
    }
    case TK_EQ:
    case TK_NE:
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:

Changes to test/index6.test.

435
436
437
438
439
440
441

442
443
444
445
446
447
448
449









450
451

do_execsql_test index6-14.2 {
  SELECT * FROM t0 WHERE CASE c0 WHEN 0 THEN 0 ELSE 1 END;
} {{} row}

# 2019-08-30
# Ticket https://www.sqlite.org/src/info/a6408d42b9f44462

#
do_execsql_test index6-15.1 {
  DROP TABLE t0;
  CREATE TABLE t0(c0);
  INSERT INTO t0(c0) VALUES (NULL);
  CREATE INDEX i0 ON t0(1) WHERE c0 NOT NULL;
  SELECT 1 FROM t0 WHERE (t0.c0 IS FALSE) IS FALSE;
} {1}










finish_test







>








>
>
>
>
>
>
>
>
>


435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461

do_execsql_test index6-14.2 {
  SELECT * FROM t0 WHERE CASE c0 WHEN 0 THEN 0 ELSE 1 END;
} {{} row}

# 2019-08-30
# Ticket https://www.sqlite.org/src/info/a6408d42b9f44462
# Ticket https://www.sqlite.org/src/info/fba33c8b1df6a915
#
do_execsql_test index6-15.1 {
  DROP TABLE t0;
  CREATE TABLE t0(c0);
  INSERT INTO t0(c0) VALUES (NULL);
  CREATE INDEX i0 ON t0(1) WHERE c0 NOT NULL;
  SELECT 1 FROM t0 WHERE (t0.c0 IS FALSE) IS FALSE;
} {1}
do_execsql_test index6-15.2 {
  SELECT 1 FROM t0 WHERE (t0.c0 IS FALSE) BETWEEN FALSE AND TRUE;
} {1}
do_execsql_test index6-15.3 {
  SELECT 1 FROM t0 WHERE TRUE BETWEEN (t0.c0 IS FALSE) AND TRUE;
} {1}
do_execsql_test index6-15.4 {
  SELECT 1 FROM t0 WHERE FALSE BETWEEN FALSE AND (t0.c0 IS FALSE);
} {1}

finish_test