SQLite

Changes On Branch simplify-or-clause
Login

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

Changes In Branch simplify-or-clause Excluding Merge-Ins

This is equivalent to a diff from 2964ce25 to a0c08d26

2015-10-29
14:29
The optimization on this branch is logically incorrect. It changes the return value of "SELECT 0 OR 'xyzzy'" FROM 0 to 'xyzzy'. (Closed-Leaf check-in: a0c08d26 user: drh tags: simplify-or-clause)
13:48
Fix uses of ctype functions (ex: isspace()) on signed characters in test programs and in some obscure extensions. No changes to the core. (check-in: 34eb6911 user: drh tags: trunk)
12:27
Apply optimizations to simplify OR clauses that contain constant terms. (check-in: d533e23f user: drh tags: simplify-or-clause)
01:11
Enhance comments in the MSVC batch build tool. (check-in: 2964ce25 user: mistachkin tags: trunk)
2015-10-28
20:01
Make the internal sqlite3PExpr() interface responsive to the TKFLG_DONTFOLD flag on the operator parameter. (check-in: b10ab59f user: drh tags: trunk)

Changes to src/expr.c.

529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
529
530
531
532
533
534
535




























536
537
538
539
540
541
542







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







      pRoot->pLeft = pLeft;
      pRoot->flags |= EP_Propagate & pLeft->flags;
    }
    exprSetHeight(pRoot);
  }
}

/*
** Allocate an Expr node which joins as many as two subtrees.
**
** One or both of the subtrees can be NULL.  Return a pointer to the new
** Expr node.  Or, if an OOM error occurs, set pParse->db->mallocFailed,
** free the subtrees and return NULL.
*/
Expr *sqlite3PExpr(
  Parse *pParse,          /* Parsing context */
  int op,                 /* Expression opcode */
  Expr *pLeft,            /* Left operand */
  Expr *pRight,           /* Right operand */
  const Token *pToken     /* Argument token */
){
  Expr *p;
  if( op==TK_AND && pParse->nErr==0 ){
    /* Take advantage of short-circuit false optimization for AND */
    p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
  }else{
    p = sqlite3ExprAlloc(pParse->db, op & TKFLG_MASK, pToken, 1);
    sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
  }
  if( p ) {
    sqlite3ExprCheckHeight(pParse, p->nHeight);
  }
  return p;
}

/*
** If the expression is always either TRUE or FALSE (respectively),
** then return 1.  If one cannot determine the truth value of the
** expression at compile-time return 0.
**
** This is an optimization.  If is OK to return 0 here even if
** the expression really is always false or false (a false negative).
607
608
609
610
611
612
613
























































614
615
616
617
618
619
620
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
  }else{
    Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0);
    sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
    return pNew;
  }
}

/* Join expressions pLeft and pRight using OR.  Apply constant-folding
** style optimizations.  For example,  "x OR 1" becomes just "1".
*/
static Expr *sqlite3ExprOr(sqlite3 *db, Expr *pLeft, Expr *pRight){
  if( pLeft && exprAlwaysFalse(pLeft) ){
    sqlite3ExprDelete(db, pLeft);
    pLeft = 0;
  }
  if( pRight==0 || exprAlwaysFalse(pRight) ){
    sqlite3ExprDelete(db, pRight);
    if( pLeft ) return pLeft;
    return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
  }
  if( pLeft==0 ) return pRight;
  if( exprAlwaysTrue(pLeft) || exprAlwaysTrue(pRight) ){
    sqlite3ExprDelete(db, pLeft);
    sqlite3ExprDelete(db, pRight);
    return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
  }else{
    Expr *pNew = sqlite3ExprAlloc(db, TK_OR, 0, 0);
    sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
    return pNew;
  }
}

/*
** Allocate an Expr node which joins as many as two subtrees.
**
** One or both of the subtrees can be NULL.  Return a pointer to the new
** Expr node.  Or, if an OOM error occurs, set pParse->db->mallocFailed,
** free the subtrees and return NULL.
*/
Expr *sqlite3PExpr(
  Parse *pParse,          /* Parsing context */
  int op,                 /* Expression opcode */
  Expr *pLeft,            /* Left operand */
  Expr *pRight,           /* Right operand */
  const Token *pToken     /* Argument token */
){
  Expr *p;
  if( pParse->nErr==0 && op==TK_AND ){
    /* Take advantage of short-circuit false optimization for AND */
    p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
  }else if( pParse->nErr==0 && op==TK_OR ){
    /* Take advantage of short-circuit false optimization for OR */
    p = sqlite3ExprOr(pParse->db, pLeft, pRight);
  }else{
    p = sqlite3ExprAlloc(pParse->db, op & TKFLG_MASK, pToken, 1);
    sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
  }
  if( p ) {
    sqlite3ExprCheckHeight(pParse, p->nHeight);
  }
  return p;
}

/*
** Construct a new expression node for a function with multiple
** arguments.
*/
Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
  Expr *pNew;