public void replaceColumnReferences(RangeVariable range, Expression[] list) {

    QueryExpression queryExpression = rangeTable.getQueryExpression();
    Expression dataExpression = rangeTable.getDataExpression();

    if (dataExpression != null) {
      dataExpression = dataExpression.replaceColumnReferences(range, list);
    }

    if (queryExpression != null) {
      queryExpression.replaceColumnReferences(range, list);
    }

    if (joinCondition != null) {
      joinCondition = joinCondition.replaceColumnReferences(range, list);
    }

    for (int i = 0; i < joinConditions.length; i++) {
      joinConditions[i].replaceColumnReferences(range, list);
    }

    for (int i = 0; i < whereConditions.length; i++) {
      whereConditions[i].replaceColumnReferences(range, list);
    }
  }
  void resolveRangeTableTypes(Session session, RangeVariable[] ranges) {

    QueryExpression queryExpression = rangeTable.getQueryExpression();

    if (queryExpression != null) {
      if (queryExpression instanceof QuerySpecification) {
        QuerySpecification qs = (QuerySpecification) queryExpression;

        if (qs.isGrouped || qs.isAggregated || qs.isOrderSensitive) {

          //
        } else {
          moveConditionsToInner(session, ranges);
        }
      }

      queryExpression.resolveTypesPartThree(session);
    }
  }
  public OrderedHashSet collectAllExpressions(
      OrderedHashSet set, OrderedIntHashSet typeSet, OrderedIntHashSet stopAtTypeSet) {

    if (joinCondition != null) {
      set = joinCondition.collectAllExpressions(set, typeSet, stopAtTypeSet);
    }

    QueryExpression queryExpression = rangeTable.getQueryExpression();
    Expression dataExpression = rangeTable.getDataExpression();

    if (queryExpression != null) {
      set = queryExpression.collectAllExpressions(set, typeSet, stopAtTypeSet);
    }

    if (dataExpression != null) {
      set = dataExpression.collectAllExpressions(set, typeSet, stopAtTypeSet);
    }

    return set;
  }
  public void resolveRangeTable(Session session, RangeGroup rangeGroup, RangeGroup[] rangeGroups) {

    QueryExpression queryExpression = rangeTable.getQueryExpression();
    Expression dataExpression = rangeTable.getDataExpression();

    if (queryExpression == null && dataExpression == null) {
      return;
    }

    rangeGroups =
        (RangeGroup[]) ArrayUtil.toAdjustedArray(rangeGroups, rangeGroup, rangeGroups.length, 1);

    if (dataExpression != null) {
      HsqlList unresolved =
          dataExpression.resolveColumnReferences(session, RangeGroup.emptyGroup, rangeGroups, null);

      unresolved =
          Expression.resolveColumnSet(
              session, RangeVariable.emptyArray, RangeGroup.emptyArray, unresolved);

      ExpressionColumn.checkColumnsResolved(unresolved);
      dataExpression.resolveTypes(session, null);
      setRangeTableVariables();
    }

    if (queryExpression != null) {
      queryExpression.resolveReferences(session, rangeGroups);

      HsqlList unresolved = queryExpression.getUnresolvedExpressions();

      unresolved =
          Expression.resolveColumnSet(
              session, RangeVariable.emptyArray, RangeGroup.emptyArray, unresolved);

      ExpressionColumn.checkColumnsResolved(unresolved);
      queryExpression.resolveTypesPartOne(session);
      queryExpression.resolveTypesPartTwo(session);
      rangeTable.prepareTable();
      setRangeTableVariables();
    }
  }
  void moveConditionsToInner(Session session, RangeVariable[] ranges) {

    Expression[] colExpr;
    int exclude;
    HsqlArrayList conditionsList;
    Expression condition = null;

    if (whereConditions.length > 1) {
      return;
    }

    if (joinConditions.length > 1) {
      return;
    }

    for (int i = 0; i < ranges.length; i++) {
      if (ranges[i].isLeftJoin || ranges[i].isRightJoin) {
        return;
      }
    }

    exclude = ArrayUtil.find(ranges, this);
    conditionsList = new HsqlArrayList();

    addConditionsToList(conditionsList, joinConditions[0].indexCond);

    if (joinConditions[0].indexCond != null
        && joinConditions[0].indexCond[0] != joinConditions[0].indexEndCond[0]) {
      addConditionsToList(conditionsList, joinConditions[0].indexEndCond);
    }

    addConditionsToList(conditionsList, whereConditions[0].indexCond);
    addConditionsToList(conditionsList, whereConditions[0].indexEndCond);
    RangeVariableResolver.decomposeAndConditions(
        session, joinConditions[0].nonIndexCondition, conditionsList);
    RangeVariableResolver.decomposeAndConditions(
        session, whereConditions[0].nonIndexCondition, conditionsList);

    for (int i = conditionsList.size() - 1; i >= 0; i--) {
      Expression e = (Expression) conditionsList.get(i);

      if (e == null || e.isTrue() || e.hasReference(ranges, exclude)) {
        conditionsList.remove(i);

        continue;
      }
    }

    if (conditionsList.size() == 0) {
      if (rangeTable.isView()) {
        ((TableDerived) rangeTable).resetToView();
      }

      return;
    }

    QueryExpression queryExpression = rangeTable.getQueryExpression();

    colExpr = ((QuerySpecification) queryExpression).exprColumns;

    for (int i = 0; i < conditionsList.size(); i++) {
      Expression e = (Expression) conditionsList.get(i);
      OrderedHashSet set = e.collectRangeVariables(null);

      e = e.duplicate();
      e = e.replaceColumnReferences(this, colExpr);

      if (e.collectAllSubqueries(null) != null) {
        return;
      }

      if (set != null) {
        for (int j = 0; j < set.size(); j++) {
          RangeVariable range = (RangeVariable) set.get(j);

          if (this != range && range.rangeType == RangeVariable.TABLE_RANGE) {
            queryExpression.setCorrelated();
          }
        }
      }

      condition = ExpressionLogical.andExpressions(condition, e);
    }

    queryExpression.addExtraConditions(condition);
  }