In example #2 there is a JOIN and a constraint that resembles a JOIN constraint, so SQLite generates a constraint entry for both sides of foo == bar without further checks. In example #4 there is no join, so SQLite correctly concludes that checking two fields of the same row for equality does not constitute a checkable constraint. EDIT: Example #2 should have only 1 constraint, just like #4.