@Override
  public void meet(IsNumeric node) throws RuntimeException {
    ValueExpr arg = node.getArg();

    // operator must be a variable or a constant
    if (arg instanceof ValueConstant) {
      try {
        Double.parseDouble(((ValueConstant) arg).getValue().stringValue());
        builder.append(Boolean.toString(true));
      } catch (NumberFormatException ex) {
        builder.append(Boolean.toString(false));
      }
    } else if (arg instanceof Var) {
      String var = getVariableAlias((Var) arg);

      Preconditions.checkState(var != null, "no alias available for variable");

      builder
          .append("(")
          .append(var)
          .append(".ntype = 'int' OR ")
          .append(var)
          .append(".ntype = 'double')");
    }
  }
  @Override
  public void meet(ValueConstant node) throws RuntimeException {
    String val = node.getValue().stringValue();

    switch (optypes.peek()) {
      case STRING:
      case URI:
        builder.append("'").append(val).append("'");
        break;
      case INT:
        builder.append(Integer.parseInt(val));
        break;
      case DECIMAL:
      case DOUBLE:
        builder.append(Double.parseDouble(val));
        break;
      case BOOL:
        builder.append(Boolean.parseBoolean(val));
        break;
      case DATE:
        builder.append("'").append(sqlDateFormat.format(DateUtils.parseDate(val))).append("'");
        break;

        // in this case we should return a node ID and also need to make sure it actually exists
      case TERM:
      case NODE:
        KiWiNode n = parent.getConverter().convert(node.getValue());
        builder.append(n.getId());
        break;

      default:
        throw new IllegalArgumentException("unsupported value type: " + optypes.peek());
    }
  }
  @Override
  public void meet(IsLiteral node) throws RuntimeException {
    ValueExpr arg = node.getArg();

    // operator must be a variable or a constant
    if (arg instanceof ValueConstant) {
      builder.append(Boolean.toString(((ValueConstant) arg).getValue() instanceof Literal));
    } else if (arg instanceof Var) {
      String var = getVariableAlias((Var) arg);

      Preconditions.checkState(var != null, "no alias available for variable");

      builder
          .append("(")
          .append(var)
          .append(".ntype = 'string' OR ")
          .append(var)
          .append(".ntype = 'int' OR ")
          .append(var)
          .append(".ntype = 'double' OR ")
          .append(var)
          .append(".ntype = 'date' OR ")
          .append(var)
          .append(".ntype = 'boolean')");
    }
  }
  @Override
  public void meet(IsBNode node) throws RuntimeException {
    ValueExpr arg = node.getArg();

    // operator must be a variable or a constant
    if (arg instanceof ValueConstant) {
      builder.append(Boolean.toString(((ValueConstant) arg).getValue() instanceof BNode));
    } else if (arg instanceof Var) {
      String var = getVariableAlias((Var) arg);

      builder.append(var).append(".ntype = 'bnode'");
    }
  }
  @Override
  public void meet(Bound node) throws RuntimeException {
    ValueExpr arg = node.getArg();

    if (arg instanceof ValueConstant) {
      builder.append(Boolean.toString(true));
    } else if (arg instanceof Var) {
      builder.append("(");
      optypes.push(ValueType.NODE);
      arg.visit(this);
      optypes.pop();
      builder.append(" IS NOT NULL)");
    }
  }