protected void initialiseIterator() {

      if (condIndex == 0) {
        hasLeftOuterRow = rangeVar.isLeftJoin;
      }

      if (conditions[condIndex].isFalse) {
        it = conditions[condIndex].rangeIndex.emptyIterator();

        return;
      }

      SubQuery subQuery = rangeVar.rangeTable.getSubQuery();

      if (subQuery != null) {
        subQuery.materialiseCorrelated(session);
      }

      if (conditions[condIndex].indexCond == null) {
        if (conditions[condIndex].reversed) {
          it = conditions[condIndex].rangeIndex.lastRow(session, store);
        } else {
          it = conditions[condIndex].rangeIndex.firstRow(session, store);
        }
      } else {
        getFirstRow();

        if (!conditions[condIndex].isJoin) {
          hasLeftOuterRow = false;
        }
      }
    }
  public void resolveRangeTable(
      Session session,
      RangeVariable[] rangeVariables,
      int rangeCount,
      RangeVariable[] outerRanges) {

    Table table = rangeTable;
    SubQuery subQuery = table.getSubQuery();

    if (subQuery != null && !subQuery.isResolved()) {
      if (subQuery.dataExpression != null) {
        HsqlList unresolved =
            subQuery.dataExpression.resolveColumnReferences(
                session, RangeVariable.emptyArray, null);

        if (unresolved != null) {
          unresolved =
              subQuery.dataExpression.resolveColumnReferences(
                  session, rangeVariables, rangeCount, null, true);
        }

        if (unresolved != null) {
          unresolved = subQuery.dataExpression.resolveColumnReferences(session, outerRanges, null);
        }

        if (unresolved != null) {
          throw Error.error(ErrorCode.X_42501, ((Expression) unresolved.get(0)).getSQL());
        }

        subQuery.dataExpression.resolveTypes(session, null);
        setRangeTableVariables();
      }

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

        HsqlList list = subQuery.queryExpression.getUnresolvedExpressions();

        // todo resolve against i ranges
        HsqlList unresolved =
            Expression.resolveColumnSet(session, rangeVariables, rangeCount, list, null);

        if (unresolved != null) {
          throw Error.error(ErrorCode.X_42501, ((Expression) unresolved.get(0)).getSQL());
        }

        subQuery.queryExpression.resolveTypes(session);
        subQuery.prepareTable(session);
        subQuery.setCorrelated();
        setRangeTableVariables();
      }
    }
  }
  void materializeSubQueries(Session session) {

    HashSet subqueryPopFlags = new HashSet();

    for (int i = 0; i < subqueries.length; i++) {
      SubQuery sq = subqueries[i];

      // VIEW working tables may be reused in a single query but they are filled only once
      if (!subqueryPopFlags.add(sq)) {
        continue;
      }

      if (!sq.isCorrelated()) {
        sq.materialise(session);
      }
    }
  }
  RangeVariable(
      Table table,
      SimpleName alias,
      OrderedHashSet columnList,
      SimpleName[] columnNameList,
      CompileContext compileContext) {

    rangeType = TABLE_RANGE;
    rangeTable = table;
    tableAlias = alias;
    columnAliases = columnList;
    columnAliasNames = columnNameList;
    joinConditions = new RangeVariableConditions[] {new RangeVariableConditions(this, true)};
    whereConditions = new RangeVariableConditions[] {new RangeVariableConditions(this, false)};

    compileContext.registerRangeVariable(this);

    SubQuery subQuery = rangeTable.getSubQuery();

    if (subQuery == null || subQuery.isResolved()) {
      setRangeTableVariables();
    }
  }