SQLite Forum

operators IS TRUE and IS FALSE missing from diagrams and table plus possible evaluation errors
Login
OK the situation is much worse than I thought it was.

Consider these cases:

```
-- example 1
sqlite> select 5 is true * 10;
0
-- example 2
sqlite> select (5 is true) * 10;
10
-- example 3
sqlite> select 5 is (true * 10);
0
```

Compare with 

```
-- example 4
sqlite> select null is not null;
0
-- example 5
sqlite> select null is (not null);
1
```

Now referring to the documentation:

>> However, if TRUE or FALSE occur on the right-hand side of an IS operator, then they form new unary postfix operators "IS TRUE" and "IS FALSE" which test the boolean value of the operand on the left.

Example 1 shows clearly that when `TRUE` is on the right side of `IS` it does not form an operator.  If it did the binding order would have to be the order shown in example 2 not the order shown in example 3.  Compare with example 4.  NOT after is forms an operator "IS NOT"  (this is correct).  It is not allowed to bind like in example 5 (without parens) that would all wrong.

What seems to be actually happening is this:

If the right operand of the `IS` operator is the literal `TRUE` then `IS` is "improved" to the operator "IS TRUE".

So I'm now thinking there is no "IS TRUE" operator at all.  This all happens in evaluation.  As you can see this makes a difference.

SQLite parses "5 is true * 10" using the precedence of `*` then the precedence of `IS`.

It's not at all clear to me that this could be changed at this point.

Looking at the source code:

```
    case TK_IS:
    case TK_ISNOT: {
      Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
      assert( !ExprHasProperty(pExpr, EP_Reduced) );
      /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
      ** and "x IS NOT FALSE". */
      if( ALWAYS(pRight) && (pRight->op==TK_ID || pRight->op==TK_TRUEFALSE) ){
        int rc = resolveExprStep(pWalker, pRight);
        if( rc==WRC_Abort ) return WRC_Abort;
        if( pRight->op==TK_TRUEFALSE ){
          pExpr->op2 = pExpr->op;
          pExpr->op = TK_TRUTH;
          return WRC_Continue;
        }
      }
      /* no break */ deliberate_fall_through
    }
```

We see the evidence.

`IS` and `IS NOT` are improved to `IS TRUE` or `IS FALSE` if the right operand is `TK_TRUEFALSE`

This means among other things that if you are trying to parse SQLite you cannot have a lexeme for "IS TRUE" and be compatible that will be all kinds of wrong.


Here's another example:

```
sqlite> select false is true < false;
1

PostgreSQL> select false is true < false;
false
PostgreSQL 9.6.17 on x86_64-pc-linux-gnu (Debian 9.6.17-2.pgdg90+1), compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit
```
I think SQLite is fundamentally wrong here.