public void meet(SqlOr node)
throws RuntimeException
{
super.meet(node);
boolean top = andAllTheWay(node);
SqlExpr sqlNull = null;
for (SqlExpr arg : node.getArgs()) {
if (arg instanceof TrueValue) {
replace(node, new TrueValue());
return;
}
else if (arg instanceof FalseValue) {
node.removeChildNode(arg);
}
else if (top && arg instanceof SqlNull) {
node.removeChildNode(arg);
}
else if (sqlNull != null && arg instanceof SqlNull) {
node.removeChildNode(arg);
}
else if (arg instanceof SqlNull) {
sqlNull = arg;
}
}
if (node.getNumberOfArguments() == 0) {
replace(node, new FalseValue());
}
else if (node.getNumberOfArguments() == 1) {
replace(node, node.getArg(0));
}
else if (sqlNull != null) {
for (SqlExpr arg : node.getArgs()) {
if (arg instanceof SqlOr) {
SqlOr nestedOr = (SqlOr)arg;
for (SqlExpr nestedArg : nestedOr.getArgs()) {
if (nestedArg instanceof SqlNull) {
nestedOr.removeChildNode(nestedArg);
}
}
if (nestedOr.getNumberOfArguments() == 0) {
replace(nestedOr, new SqlNull());
}
else if (nestedOr.getNumberOfArguments() == 1) {
replace(nestedOr, nestedOr.getArg(0));
}
}
else if (arg instanceof SqlAnd) {
// value IS NOT NULL AND value = ? OR NULL
// -> value = ?
SqlAnd and = (SqlAnd)arg;
// search for the value IS NOT NULL expression
for (SqlExpr isNotNull : and.getArgs()) {
SqlExpr variable = arg(arg(isNotNull, SqlNot.class), SqlIsNull.class);
if (variable == null) {
continue;
}
// search for the value = ? expression
for (SqlExpr eq : and.getArgs()) {
SqlExpr constant = other(eq, variable, SqlEq.class);
if (constant == null) {
continue;
}
if (constant instanceof SqlConstant) {
node.removeChildNode(sqlNull);