@Override
 public void meet(SqlCase node) throws RuntimeException {
   super.meet(node);
   List<Entry> entries = node.getEntries();
   for (SqlCase.Entry e : entries) {
     if (e.getCondition() instanceof SqlNull) {
       node.removeEntry(e);
     } else if (e.getCondition() instanceof FalseValue) {
       node.removeEntry(e);
     } else if (e.getCondition() instanceof TrueValue) {
       node.truncateEntries(e);
       break;
     }
   }
   entries = node.getEntries();
   if (entries.isEmpty()) {
     replace(node, new SqlNull());
   } else if (entries.size() == 1) {
     Entry entry = entries.get(0);
     if (entry.getCondition() instanceof TrueValue) {
       replace(node, entry.getResult().clone());
     } else if (entry.getCondition() instanceof FalseValue) {
       replace(node, new SqlNull());
     } else if (entry.getCondition() instanceof SqlNot) {
       SqlNot not = (SqlNot) entry.getCondition();
       if (not.getArg() instanceof SqlIsNull) {
         SqlIsNull is = (SqlIsNull) not.getArg();
         if (is.getArg().equals(entry.getResult())) {
           replace(node, entry.getResult().clone());
         }
       }
     }
   }
 }
 @Override
 public void meet(SqlNot node) throws RuntimeException {
   super.meet(node);
   SqlExpr arg = node.getArg();
   if (arg instanceof TrueValue) {
     replace(node, new FalseValue());
   } else if (arg instanceof FalseValue) {
     replace(node, new TrueValue());
   } else if (arg instanceof SqlNull) {
     replace(node, new SqlNull());
   } else if (arg instanceof SqlNot) {
     SqlNot not = (SqlNot) arg;
     replace(node, not.getArg().clone());
   } else if (arg instanceof SqlOr) {
     SqlOr or = (SqlOr) arg;
     replace(node, and(not(or.getLeftArg().clone()), not(or.getRightArg().clone())));
   }
 }