Here's an updated patch with the visitor renamed to ConstantExpressionVisitor, the method in ValueNode renamed to evaluateConstantExpression(), and with updated comments.
Description of the other changes from the previous patch:
1) The invocation of the visitor is moved to DMLStatementNode.optimizeStatement(). The previous patch called it from SelectNode and JoinNode on WHERE/HAVING/ON clauses. As mentioned by Bryan, this transformation can be useful in other parts of the tree as well (as seen in VALUES 1+3, although evaluation of arithmetic operations hasn't implemented). I think it's cleaner to have the invocation at one single location. Also, since there might be sub-queries inside WHERE clauses, the old patch might traverse some parts of the tree many times.
The visitor now walks the entire query tree between the preprocessing phase and the optimization phase. Doing it as late as possible is advantageous because then other simplifications (like the NOT elimination performed in preprocess()) increase the chances of finding expressions with a know value, but it should be performed before optimization so that the optimizer can take advantage of the more accurate selectivity predictions.
2) JoinNode: Made acceptChildren() call accept() on joinPredicates. The previous patch visited the JoinNode a little earlier, when the ON clause was still represented by joinClause, whereas this patch visits the JoinNode after the predicates have been moved to joinPredicates. There are also other children of JoinNode that are not visited, but I didn't do anything with them for now.
3) BinaryRelationalOperatorNode: Added rewriting for less-than and less-equals, which were forgotten in the previous patch.
4) logop.out: Accept that a statement that used to fail with arithmetic overflow now succeeds because the arithmetic isn't performed at runtime. The statement that fails is
> select x from s where 2147483647 + 10 = 2 and (1=2);
whereas this almost identical one is expected to succeed
> select x from s where (1=2) and 2147483647 + 10 = 2;
I'm not aware of anything in the SQL standard that requires us to evaluate the arithmetic expression first, so I think it's equally OK to pass the first statement as it is to pass the second statement. The comments in the test also indicate this.
4) specjPlans.out: Removed unneeded ProjectRestrictResultSet from two of the query plans (they were there to enforce the restriction 1=1).
5) outerjoin.out: Updated query plan from nested loop join to hash join in a join with 1=1 in the ON clause. New plan looks OK and the results are still correct. The plan probably changed because 1=1 and TRUE have different (estimated) selectivity.
I haven't run all the regression tests on the latest revision of the patch. Will report back when I have the results.