  Many important query processing methods proactively use semijoins or
semijoin-like filters to delete dangling tuples, i.e., tuples that do not
appear in the final query result. Semijoin methods can achieve formal
optimality but have high upfront cost in practice. Filter methods reduce the
cost but lose the optimality guarantee.
  We propose a new join algorithm, TreeTracker Join ($\mathsf{TTJ}$), that
achieves the data complexity optimality for acyclic conjunctive queries (ACQs)
without semijoins or semijoin-like filters. $\mathsf{TTJ}$ leverages join
failure events, where a tuple from one of the relations of a binary join
operator fails to match any tuples from the other relation. $\mathsf{TTJ}$
starts join evaluation immediately and when join fails, $\mathsf{TTJ}$
identifies the tuple as dangling and prevents it from further consideration in
the execution of the query. The design of $\mathsf{TTJ}$ exploits the
connection between query evaluation and constraint satisfaction problem (CSP)
by treating a join tree of an ACQ as a constraint network and the query
evaluation as a CSP search problem. $\mathsf{TTJ}$ is a direct extension of a
CSP algorithm, TreeTracker, that embodies two search techniques backjumping and
no-good. We establish that join tree and plan can be constructed from each
other in order to incorporate the search techniques into physical operators in
the iterator form. We compare $\mathsf{TTJ}$ with hash-join, a classic semijoin
method: Yannakakis's algorithm, and two contemporary filter methods: Predicate
Transfer and Lookahead Information Passing. Favorable empirical results are
developed using standard query benchmarks: JOB, TPC-H, and SSB.
