/**
   * Chooses certain query conditions and assigns a copy of them to this filter. The original
   * condition is set to Expression.TRUE once assigned.
   *
   * @param condition
   * @throws HsqlException
   */
  void setConditions(Expression condition) throws HsqlException {

    setCondition(condition);

    if (filterIndex == null) {
      filterIndex = filterTable.getPrimaryIndex();
    }

    if (filterIndex.getVisibleColumns() == 1
        || eStart == null
        || eAnd == null
        || eStart.exprType != Expression.EQUAL) {
      return;
    }

    boolean[] check = filterTable.getNewColumnCheckList();
    Expression[] expr = new Expression[check.length];
    int colindex = eStart.getArg().getColumnNr();

    check[colindex] = true;
    expr[colindex] = eStart.getArg2();

    eAnd.getEquiJoinColumns(this, check, expr);

    if (ArrayUtil.containsAllTrueElements(check, filterIndex.colCheck)) {
      isMultiFindFirst = true;
      findFirstExpressions = expr;
    }
  }
  private void setCondition(Expression e) throws HsqlException {

    int type = e.getType();
    Expression e1 = e.getArg();
    Expression e2 = e.getArg2();

    this.isAssigned = true;

    if (type == Expression.AND) {
      setCondition(e1);
      setCondition(e2);

      return;
    }

    int conditionType = toConditionType(type);

    if (conditionType == CONDITION_NONE) {

      // not a condition expression
      return;
    }

    // fredt@users 20030813 - patch 1.7.2 - fix for column comparison within same table bugs #572075
    // and 722443
    if (e1.getFilter() == this && e2.getFilter() == this) {
      conditionType = CONDITION_UNORDERED;
    } else if (e1.getFilter() == this) {

      // ok include this
    } else if ((e2.getFilter() == this) && (conditionType != CONDITION_UNORDERED)) {

      // swap and try again to allow index usage
      e.swapCondition();
      setCondition(e);

      return;
    } else if (e1.outerFilter == this) {

      // fredt - this test is last to allow swapping the terms above
      conditionType = CONDITION_OUTER;
    } else {

      // unrelated: don't include
      return;
    }

    //        Trace.doAssert(e1.getFilter() == this, "setCondition");
    if (!e2.isResolved()) {
      return;
    }

    // fredt - condition defined in outer but not this one
    if (e1.outerFilter != null && e1.outerFilter != this) {
      return;
    }

    if (conditionType == CONDITION_UNORDERED) {
      if (!isOuterJoin) {
        addAndCondition(e);
      }

      return;
    }

    if (conditionType == CONDITION_OUTER) {
      addAndCondition(e);
      e.setTrue();

      return;
    }

    int i = e1.getColumnNr();
    Index index = filterTable.getIndexForColumn(i);

    if (index == null || (filterIndex != index && filterIndex != null)) {
      addAndCondition(e);

      return;
    }

    filterIndex = index;

    switch (conditionType) {
      case CONDITION_START_END:
        {

          // candidate for both start and end
          if ((eStart != null) || (eEnd != null)) {
            addAndCondition(e);

            return;
          }

          eStart = new Expression(e);
          eEnd = eStart;

          break;
        }
      case CONDITION_START:
        {

          // candidate for start
          if (eStart != null) {
            addAndCondition(e);

            return;
          }

          eStart = new Expression(e);

          break;
        }
      case CONDITION_END:
        {

          // candidate for end
          if (eEnd != null) {
            addAndCondition(e);

            return;
          }

          eEnd = new Expression(e);

          break;
        }
    }

    e.setTrue();
  }