private RDFRectangle toRectangle(StatementPattern pattern, BindingSet bindings) {
    Value sVal = pattern.getSubjectVar().getValue();
    Value pVal = pattern.getPredicateVar().getValue();
    Value oVal = pattern.getObjectVar().getValue();

    RDFURIRange subjectRange;
    List<String> list = new ArrayList<String>();
    if (sVal == null) {
      if (bindings.hasBinding(pattern.getSubjectVar().getName()))
        list.add(bindings.getValue(pattern.getSubjectVar().getName()).stringValue());
    } else list.add(sVal.stringValue());

    if (!list.isEmpty()) subjectRange = new RDFURIRange(list);
    else subjectRange = new RDFURIRange();

    ExplicitSetRange<URI> predicateRange;
    Set<URI> set = new HashSet<URI>();
    if (pVal == null) {
      if (bindings.hasBinding(pattern.getPredicateVar().getName()))
        set.add((URI) bindings.getValue(pattern.getPredicateVar().getName()));
    } else set.add((URI) pVal);

    if (!set.isEmpty()) predicateRange = new ExplicitSetRange<URI>(set);
    else predicateRange = new ExplicitSetRange<>();

    RDFValueRange objectRange = new RDFValueRange();
    if (oVal == null) {
      if (bindings.hasBinding(pattern.getObjectVar().getName()))
        objectRange = fillObjectRange(bindings.getValue(pattern.getObjectVar().getName()));
    } else objectRange = fillObjectRange(oVal);

    return new RDFRectangle(subjectRange, predicateRange, objectRange);
  }
  @Override
  public void meet(Count node) throws RuntimeException {
    builder.append("COUNT(");

    if (node.isDistinct()) {
      builder.append("DISTINCT ");
    }

    if (node.getArg() == null) {
      // this is a weird special case where we need to expand to all variables selected in the query
      // wrapped
      // by the group; we cannot simply use "*" because the concept of variables is a different one
      // in SQL,
      // so instead we construct an ARRAY of the bindings of all variables

      List<String> countVariables = new ArrayList<>();
      for (SQLVariable v : parent.getVariables().values()) {
        if (v.getProjectionType() == ValueType.NONE) {
          Preconditions.checkState(
              v.getExpressions().size() > 0, "no expressions available for variable");

          countVariables.add(v.getExpressions().get(0));
        }
      }
      builder.append("ARRAY[");
      Joiner.on(',').appendTo(builder, countVariables);
      builder.append("]");

    } else {
      optypes.push(ValueType.NODE);
      node.getArg().visit(this);
      optypes.pop();
    }
    builder.append(")");
  }