org.hsqldb.RangeVariable Maven / Gradle / Ivy
Show all versions of sqltool Show documentation
/* Copyright (c) 2001-2021, The HSQL Development Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.hsqldb;
import org.hsqldb.HsqlNameManager.SimpleName;
import org.hsqldb.ParserDQL.CompileContext;
import org.hsqldb.RangeGroup.RangeGroupSimple;
import org.hsqldb.error.Error;
import org.hsqldb.error.ErrorCode;
import org.hsqldb.index.Index;
import org.hsqldb.lib.ArrayUtil;
import org.hsqldb.lib.HashMap;
import org.hsqldb.lib.HashSet;
import org.hsqldb.lib.HsqlArrayList;
import org.hsqldb.lib.List;
import org.hsqldb.lib.OrderedHashMap;
import org.hsqldb.lib.OrderedHashSet;
import org.hsqldb.lib.OrderedIntHashSet;
import org.hsqldb.lib.OrderedLongHashSet;
import org.hsqldb.navigator.RangeIterator;
import org.hsqldb.navigator.RowIterator;
import org.hsqldb.persist.PersistentStore;
import org.hsqldb.types.Type;
/**
* Metadata for range variables, including conditions.
*
* @author Fred Toussi (fredt@users dot sourceforge.net)
* @version 2.6.1
* @since 1.9.0
*/
public class RangeVariable {
static final RangeVariable[] emptyArray = new RangeVariable[]{};
//
public static final int TABLE_RANGE = 1;
public static final int TRANSITION_RANGE = 2;
public static final int PARAMETER_RANGE = 3;
public static final int VARIALBE_RANGE = 4;
public static final int PLACEHOLDER_RANGE = 5;
//
Table rangeTable;
final SimpleName tableAlias;
private OrderedHashSet columnAliases;
private SimpleName[] columnAliasNames;
private OrderedHashSet columnNames;
OrderedHashSet namedJoinColumns;
HashMap namedJoinColumnExpressions;
boolean[] columnsInGroupBy;
boolean hasKeyedColumnInGroupBy;
boolean[] usedColumns;
boolean[] updatedColumns;
boolean[] namedJoinColumnCheck;
//
RangeVariableConditions[] joinConditions;
RangeVariableConditions[] whereConditions;
int subRangeCount;
// non-index conditions
Expression joinCondition;
// system period condition
ExpressionPeriodOp periodCondition;
// role based condition
Expression filterCondition;
//
boolean isLateral;
boolean isLeftJoin; // table joined with LEFT / FULL OUTER JOIN
boolean isRightJoin; // table joined with RIGHT / FULL OUTER JOIN
boolean isJoin;
//
boolean hasLateral;
boolean hasLeftJoin;
boolean hasRightJoin;
//
int level;
//
int indexDistinctCount;
//
int rangePositionInJoin;
//
int rangePosition;
//
boolean isViewSubquery;
// for variable and parameter lists
OrderedHashMap variables;
// variable, parameter, table
int rangeType;
//
boolean isGenerated;
public RangeVariable(OrderedHashMap variables, SimpleName rangeName,
boolean isVariable, int rangeType) {
this.variables = variables;
this.rangeType = rangeType;
rangeTable = null;
tableAlias = rangeName;
columnsInGroupBy = null;
usedColumns = null;
joinConditions = new RangeVariableConditions[]{
new RangeVariableConditions(this, true) };
whereConditions = new RangeVariableConditions[]{
new RangeVariableConditions(this, false) };
switch (rangeType) {
case TRANSITION_RANGE :
usedColumns = new boolean[variables.size()];
break;
case PARAMETER_RANGE :
case VARIALBE_RANGE :
case PLACEHOLDER_RANGE :
break;
default :
throw Error.runtimeError(ErrorCode.U_S0500, "RangeVariable");
}
}
public 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);
if (rangeTable.getColumnCount() != 0) {
setRangeTableVariables();
}
}
public RangeVariable(Table table, int position) {
rangeType = TABLE_RANGE;
rangeTable = table;
tableAlias = null;
columnsInGroupBy = rangeTable.getNewColumnCheckList();
usedColumns = rangeTable.getNewColumnCheckList();
rangePosition = position;
joinConditions = new RangeVariableConditions[]{
new RangeVariableConditions(this, true) };
whereConditions = new RangeVariableConditions[]{
new RangeVariableConditions(this, false) };
}
public void setRangeTableVariables() {
if (columnAliasNames != null
&& rangeTable.getColumnCount() != columnAliasNames.length) {
throw Error.error(ErrorCode.X_42593);
}
columnsInGroupBy = rangeTable.getNewColumnCheckList();
usedColumns = rangeTable.getNewColumnCheckList();
joinConditions[0].rangeIndex = rangeTable.getDefaultIndex();
whereConditions[0].rangeIndex = rangeTable.getDefaultIndex();
}
public void setJoinType(boolean isLeft, boolean isRight) {
isJoin = true;
isLeftJoin = isLeft;
isRightJoin = isRight;
if (isRightJoin) {
whereConditions[0].rangeIndex = rangeTable.getPrimaryIndex();
}
}
public void setSystemPeriodCondition(ExpressionPeriodOp condition) {
periodCondition = condition;
}
public void setFilterExpression(Session session, Expression expr) {
if (expr != null) {
RangeGroup ranges =
new RangeGroupSimple(new RangeVariable[]{ this }, false);
expr.resolveColumnReferences(session, ranges,
RangeGroup.emptyArray, null);
expr.resolveTypes(session, null);
filterCondition = expr;
}
}
public void addNamedJoinColumns(OrderedHashSet columns) {
namedJoinColumns = columns;
}
public void addColumn(int columnIndex) {
if (usedColumns != null) {
usedColumns[columnIndex] = true;
}
}
public void addAllColumns() {
if (usedColumns != null) {
ArrayUtil.fillArray(usedColumns, true);
}
}
public void addNamedJoinColumnExpression(String name, Expression e,
int position) {
if (namedJoinColumnExpressions == null) {
namedJoinColumnExpressions = new HashMap();
}
namedJoinColumnExpressions.put(name, e);
if (namedJoinColumnCheck == null) {
namedJoinColumnCheck = rangeTable.getNewColumnCheckList();
}
namedJoinColumnCheck[position] = true;
}
public ExpressionColumn getColumnExpression(String name) {
return namedJoinColumnExpressions == null ? null
: (ExpressionColumn) namedJoinColumnExpressions
.get(name);
}
public Table getTable() {
return rangeTable;
}
public boolean hasAnyTerminalCondition() {
for (int i = 0; i < joinConditions.length; i++) {
if (joinConditions[0].terminalCondition != null) {
return true;
}
}
for (int i = 0; i < whereConditions.length; i++) {
if (whereConditions[0].terminalCondition != null) {
return true;
}
}
return false;
}
public boolean hasAnyIndexCondition() {
for (int i = 0; i < joinConditions.length; i++) {
if (joinConditions[0].indexedColumnCount > 0) {
return true;
}
}
for (int i = 0; i < whereConditions.length; i++) {
if (whereConditions[0].indexedColumnCount > 0) {
return true;
}
}
return false;
}
public boolean hasSingleIndexCondition() {
return joinConditions.length == 1
&& joinConditions[0].indexedColumnCount > 0;
}
public boolean setDistinctColumnsOnIndex(int[] colMap) {
if (joinConditions.length != 1) {
return false;
}
int[] indexColMap = joinConditions[0].rangeIndex.getColumns();
if (colMap.length > indexColMap.length) {
return false;
}
if (colMap.length == indexColMap.length) {
if (ArrayUtil.haveEqualSets(colMap, indexColMap, colMap.length)) {
indexDistinctCount = colMap.length;
return true;
}
}
if (ArrayUtil.haveEqualArrays(colMap, indexColMap, colMap.length)) {
indexDistinctCount = colMap.length;
return true;
}
return false;
}
/**
* Used for sort
*/
public Index getSortIndex() {
if (joinConditions.length == 1) {
return joinConditions[0].rangeIndex;
} else {
return null;
}
}
/**
* Used for sort
*/
public boolean setSortIndex(Index index, boolean reversed) {
if (joinConditions.length == 1) {
if (joinConditions[0].indexedColumnCount == 0) {
joinConditions[0].rangeIndex = index;
joinConditions[0].reversed = reversed;
return true;
}
}
return false;
}
public boolean reverseOrder() {
if (joinConditions.length == 1) {
joinConditions[0].reverseIndexCondition();
return true;
}
return false;
}
public OrderedHashSet getColumnNames() {
if (columnNames == null) {
columnNames = new OrderedHashSet();
rangeTable.getColumnNames(this.usedColumns, columnNames);
}
return columnNames;
}
public OrderedHashSet getUniqueColumnNameSet() {
OrderedHashSet set = new OrderedHashSet();
if (columnAliases != null) {
set.addAll(columnAliases);
return set;
}
for (int i = 0; i < rangeTable.columnList.size(); i++) {
String name = rangeTable.getColumn(i).getName().name;
boolean added = set.add(name);
if (!added) {
throw Error.error(ErrorCode.X_42578, name);
}
}
return set;
}
public int findColumn(String schemaName, String tableName,
String columnName) {
if (namedJoinColumnExpressions != null
&& namedJoinColumnExpressions.containsKey(columnName)) {
if (tableName != null && !resolvesTableName(tableName)) {
return -1;
}
}
if (resolvesSchemaAndTableName(schemaName, tableName)) {
return findColumn(columnName);
}
return -1;
}
/**
* Returns index for column
*
* @param columnName name of column
* @return int index or -1 if not found
*/
public int findColumn(String columnName) {
if (variables != null) {
return variables.getIndex(columnName);
} else if (columnAliases != null) {
return columnAliases.getIndex(columnName);
} else {
return rangeTable.findColumn(columnName);
}
}
public ColumnSchema getColumn(int i) {
if (variables == null) {
return rangeTable.getColumn(i);
} else {
return (ColumnSchema) variables.get(i);
}
}
public SimpleName getColumnAlias(int i) {
if (columnAliases == null) {
return rangeTable.getColumn(i).getName();
} else {
return columnAliasNames[i];
}
}
public boolean hasColumnAlias() {
return columnAliases != null;
}
public boolean hasTableAlias() {
return tableAlias != null;
}
public boolean isVariable() {
return variables != null;
}
public SimpleName getTableAlias() {
return tableAlias == null ? rangeTable.getName()
: tableAlias;
}
public RangeVariable getRangeForTableName(String name) {
if (resolvesTableName(name)) {
return this;
}
return null;
}
private boolean resolvesSchemaAndTableName(String schemaName,
String tableName) {
return resolvesSchemaName(schemaName) && resolvesTableName(tableName);
}
private boolean resolvesTableName(String name) {
if (name == null) {
return true;
}
if (variables != null) {
if (tableAlias != null) {
return name.equals(tableAlias.name);
}
return false;
}
if (tableAlias == null) {
if (name.equals(rangeTable.getName().name)) {
return true;
}
} else if (name.equals(tableAlias.name)) {
return true;
}
return false;
}
private boolean resolvesSchemaName(String name) {
if (name == null) {
return true;
}
if (variables != null) {
return false;
}
if (tableAlias != null) {
return false;
}
return name.equals(rangeTable.getSchemaName().name);
}
public PeriodDefinition findPeriod(String schemaName, String tableName,
String periodName) {
if (resolvesSchemaAndTableName(schemaName, tableName)) {
PeriodDefinition period = rangeTable.getApplicationPeriod();
if (period != null && period.getName().name.equals(periodName)) {
return period;
}
period = rangeTable.getSystemPeriod();
if (period != null && period.getName().name.equals(periodName)) {
return period;
}
}
return null;
}
/**
* Add all columns to a list of expressions
*/
public void addTableColumns(HsqlArrayList exprList) {
if (namedJoinColumns != null) {
int count = exprList.size();
int position = 0;
for (int i = 0; i < count; i++) {
Expression e = (Expression) exprList.get(i);
String columnName = e.getColumnName();
if (namedJoinColumns.contains(columnName)) {
if (position != i) {
exprList.remove(i);
exprList.add(position, e);
}
e = getColumnExpression(columnName);
exprList.set(position, e);
position++;
}
}
}
addTableColumns(exprList, exprList.size(), namedJoinColumns);
}
/**
* Add all columns to a list of expressions
*/
public int addTableColumns(HsqlArrayList exprList, int position,
HashSet exclude) {
Table table = getTable();
int count = table.getColumnCount();
for (int i = 0; i < count; i++) {
ColumnSchema column = table.getColumn(i);
String columnName = columnAliases == null ? column.getName().name
: (String) columnAliases
.get(i);
if (exclude != null && exclude.contains(columnName)) {
continue;
}
Expression e = new ExpressionColumn(this, i);
exprList.add(position++, e);
}
return position;
}
public void addTableColumns(RangeVariable subRange, Expression expression,
HashSet exclude) {
if (subRange == this) {
Table table = getTable();
int count = table.getColumnCount();
addTableColumns(expression, 0, count, exclude);
}
}
protected int getFirstColumnIndex(RangeVariable subRange) {
if (subRange == this) {
return 0;
}
return -1;
}
protected void addTableColumns(Expression expression, int start,
int count, HashSet exclude) {
Table table = getTable();
HsqlArrayList list = new HsqlArrayList();
for (int i = start; i < start + count; i++) {
ColumnSchema column = table.getColumn(i);
String columnName = columnAliases == null ? column.getName().name
: (String) columnAliases
.get(i);
if (exclude != null && exclude.contains(columnName)) {
continue;
}
Expression e = new ExpressionColumn(this, i);
list.add(e);
}
Expression[] nodes = new Expression[list.size()];
list.toArray(nodes);
expression.nodes = nodes;
}
/**
* Removes reference to Index to avoid possible memory leaks after alter
* table or drop index
*/
public void setForCheckConstraint() {
joinConditions[0].rangeIndex = null;
whereConditions[0].rangeIndex = null;
rangePosition = 0;
}
/**
* used before condition processing
*/
public Expression getJoinCondition() {
return joinCondition;
}
public void addJoinCondition(Expression e) {
joinCondition = ExpressionLogical.andExpressions(joinCondition, e);
}
public void resetConditions() {
Index index = joinConditions[0].rangeIndex;
joinConditions = new RangeVariableConditions[]{
new RangeVariableConditions(this, true) };
joinConditions[0].rangeIndex = index;
//
index = whereConditions[0].rangeIndex;
whereConditions = new RangeVariableConditions[]{
new RangeVariableConditions(this, false) };
whereConditions[0].rangeIndex = index;
}
public OrderedHashSet getSubqueries() {
OrderedHashSet set = null;
if (joinCondition != null) {
set = joinCondition.collectAllSubqueries(set);
}
if (rangeTable instanceof TableDerived) {
QueryExpression queryExpression = rangeTable.getQueryExpression();
if (queryExpression == null) {
Expression dataExpression = rangeTable.getDataExpression();
if (dataExpression != null) {
if (set == null) {
set = new OrderedHashSet();
}
OrderedHashSet.addAll(set, dataExpression.getSubqueries());
}
} else {
OrderedHashSet temp = queryExpression.getSubqueries();
set = OrderedHashSet.addAll(set, temp);
set = OrderedHashSet.add(set, rangeTable);
}
}
return set;
}
OrderedHashSet collectRangeVariables(RangeVariable[] rangeVars,
OrderedHashSet set) {
QueryExpression queryExpression = rangeTable.getQueryExpression();
Expression dataExpression = rangeTable.getDataExpression();
if (queryExpression != null) {
set = queryExpression.collectRangeVariables(rangeVars, set);
}
if (dataExpression != null) {
set = dataExpression.collectRangeVariables(rangeVars, set);
}
return set;
}
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 replaceColumnReferences(Session session, RangeVariable range,
Expression[] list) {
QueryExpression queryExpression = rangeTable.getQueryExpression();
Expression dataExpression = rangeTable.getDataExpression();
if (dataExpression != null) {
dataExpression.replaceColumnReferences(session, range, list);
}
if (queryExpression != null) {
queryExpression.replaceColumnReferences(session, range, list);
}
if (joinCondition != null) {
joinCondition = joinCondition.replaceColumnReferences(session,
range, list);
}
for (int i = 0; i < joinConditions.length; i++) {
joinConditions[i].replaceColumnReferences(session, range, list);
}
for (int i = 0; i < whereConditions.length; i++) {
whereConditions[i].replaceColumnReferences(session, range, list);
}
}
public void replaceRangeVariables(RangeVariable[] ranges,
RangeVariable[] newRanges) {
if (joinCondition != null) {
joinCondition.replaceRangeVariables(ranges, newRanges);
}
}
public void replaceExpressions(OrderedHashSet expressions,
int resultRangePosition) {
QueryExpression queryExpression = rangeTable.getQueryExpression();
Expression dataExpression = rangeTable.getDataExpression();
if (dataExpression != null) {
dataExpression.replaceExpressions(expressions,
resultRangePosition);
}
if (queryExpression != null) {
queryExpression.replaceExpressions(expressions,
resultRangePosition);
}
if (joinCondition != null) {
joinCondition = joinCondition.replaceExpressions(expressions,
resultRangePosition);
}
for (int i = 0; i < joinConditions.length; i++) {
joinConditions[i].replaceExpressions(expressions,
resultRangePosition);
}
for (int i = 0; i < whereConditions.length; i++) {
whereConditions[i].replaceExpressions(expressions,
resultRangePosition);
}
}
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) {
List 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);
List unresolved = queryExpression.getUnresolvedExpressions();
unresolved = Expression.resolveColumnSet(session,
RangeVariable.emptyArray, RangeGroup.emptyArray,
unresolved);
ExpressionColumn.checkColumnsResolved(unresolved);
queryExpression.resolveTypesPartOne(session);
queryExpression.resolveTypesPartTwo(session);
rangeTable.prepareTable(session);
setRangeTableVariables();
}
}
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);
}
}
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);
}
}
if (conditionsList.size() == 0) {
if (rangeTable.isView()) {
((TableDerived) rangeTable).resetToView();
}
return;
}
OrderedHashSet subquerySet = null;
for (int i = 0; i < conditionsList.size(); i++) {
Expression e = (Expression) conditionsList.get(i);
subquerySet = e.collectAllSubqueries(subquerySet);
if (subquerySet != null) {
return;
}
}
QueryExpression queryExpression = rangeTable.getQueryExpression();
colExpr = ((QuerySpecification) queryExpression).exprColumns;
for (int i = 0; i < conditionsList.size(); i++) {
Expression e = (Expression) conditionsList.get(i);
e = e.duplicate();
e = e.replaceColumnReferences(session, this, colExpr);
OrderedHashSet set = e.collectRangeVariables(null);
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();
break;
}
}
}
condition = ExpressionLogical.andExpressions(condition, e);
}
queryExpression.addExtraConditions(condition);
}
private static void addConditionsToList(HsqlArrayList list,
Expression[] array) {
if (array == null) {
return;
}
for (int i = 0; i < array.length; i++) {
if (array[i] != null) {
if (array[i].isSingleColumnCondition
|| array[i].isSingleColumnNull
|| array[i].isSingleColumnNotNull) {
list.add(array[i]);
}
}
}
}
/**
* Retrieves a String representation of this obejct.
*
* The returned String describes this object's table, alias
* access mode, index, join mode, Start, End and And conditions.
*
* @return a String representation of this object
*/
public String describe(Session session, int blanks) {
StringBuilder sb;
StringBuilder b = new StringBuilder(blanks);
for (int i = 0; i < blanks; i++) {
b.append(' ');
}
sb = new StringBuilder();
String temp = "INNER";
if (isLeftJoin) {
temp = "LEFT OUTER";
if (isRightJoin) {
temp = "FULL";
}
} else if (isRightJoin) {
temp = "RIGHT OUTER";
}
sb.append(b).append("join type=").append(temp).append("\n");
sb.append(b).append("table=").append(rangeTable.getName().name).append(
"\n");
if (tableAlias != null) {
sb.append(b).append("alias=").append(tableAlias.name).append("\n");
}
RangeVariableConditions[] conditions = joinConditions;
if (whereConditions[0].hasIndexCondition()) {
conditions = whereConditions;
}
sb.append(b).append("cardinality=");
sb.append(rangeTable.getRowStore(session).elementCount()).append("\n");
boolean fullScan = !conditions[0].hasIndexCondition();
sb.append(b);
if (conditions == whereConditions) {
if (joinConditions[0].nonIndexCondition != null) {
sb.append("join condition = [");
sb.append(joinConditions[0].nonIndexCondition.describe(session,
blanks));
sb.append(b).append("]\n");
sb.append(b);
}
}
sb.append("access=").append(fullScan ? "FULL SCAN"
: "INDEX PRED").append("\n");
for (int i = 0; i < conditions.length; i++) {
if (i > 0) {
sb.append(b).append("OR condition = [");
} else {
sb.append(b);
if (conditions == whereConditions) {
sb.append("where condition = [");
} else {
sb.append("join condition = [");
}
}
sb.append(conditions[i].describe(session, blanks + 2));
sb.append(b).append("]\n");
}
if (conditions == joinConditions) {
sb.append(b);
if (whereConditions[0].nonIndexCondition != null) {
sb.append("where condition = [");
sb.append(
whereConditions[0].nonIndexCondition.describe(
session, blanks));
sb.append(b).append("]\n");
sb.append(b);
}
}
return sb.toString();
}
public RangeIteratorMain getIterator(Session session) {
RangeIteratorMain it;
if (this.isRightJoin) {
it = new RangeIteratorRight(session, this, null);
} else {
it = new RangeIteratorMain(session, this);
}
session.sessionContext.setRangeIterator(it);
return it;
}
public static RangeIterator getIterator(Session session,
RangeVariable[] rangeVars) {
if (rangeVars.length == 1) {
return rangeVars[0].getIterator(session);
}
RangeIteratorMain[] iterators =
new RangeIteratorMain[rangeVars.length];
for (int i = 0; i < rangeVars.length; i++) {
iterators[i] = rangeVars[i].getIterator(session);
}
return new RangeIteratorJoined(iterators);
}
public static class RangeIteratorBase implements RangeIterator {
Session session;
int rangePosition;
RowIterator it = RangeIterator.emptyRowIterator;
PersistentStore store;
boolean isBeforeFirst;
RangeVariable rangeVar;
private RangeIteratorBase() {}
public boolean isBeforeFirst() {
return isBeforeFirst;
}
public boolean next() {
if (isBeforeFirst) {
isBeforeFirst = false;
} else {
if (it == RangeIterator.emptyRowIterator) {
return false;
}
}
if (session.abortTransaction) {
throw Error.error(ErrorCode.X_40000);
}
if (session.abortAction) {
throw Error.error(ErrorCode.X_40502);
}
if (it.next()) {
return true;
} else {
return false;
}
}
public Row getCurrentRow() {
return it.getCurrentRow();
}
public Object[] getCurrent() {
return it.getCurrent();
}
public Object getField(int col) {
return it.getField(col);
}
public void setCurrent(Object[] data) {
throw Error.runtimeError(ErrorCode.U_S0500, "RangeVariable");
}
public long getRowId() {
return ((long) rangeVar.rangeTable.getId() << 32) + it.getRowId();
}
public void removeCurrent() {}
public void reset() {
it.release();
it = RangeIterator.emptyRowIterator;
isBeforeFirst = true;
}
public int getRangePosition() {
return rangePosition;
}
public boolean hasNext() {
throw Error.runtimeError(ErrorCode.U_S0500, "RangeVariable");
}
public void release() {
it.release();
}
}
public static class RangeIteratorMain extends RangeIteratorBase {
boolean hasLeftOuterRow;
boolean isFullIterator;
RangeVariableConditions[] conditions;
RangeVariableConditions[] whereConditions;
RangeVariableConditions[] joinConditions;
ExpressionPeriodOp periodCondition;
Expression filterCondition;
int condIndex = 0;
//
OrderedLongHashSet lookup;
//
Object[] currentJoinData = null;
RangeIteratorMain() {
super();
}
private RangeIteratorMain(Session session, RangeVariable rangeVar) {
this.rangePosition = rangeVar.rangePosition;
this.store = rangeVar.rangeTable.getRowStore(session);
this.session = session;
this.rangeVar = rangeVar;
isBeforeFirst = true;
whereConditions = rangeVar.whereConditions;
joinConditions = rangeVar.joinConditions;
periodCondition = rangeVar.periodCondition;
filterCondition = rangeVar.filterCondition;
if (rangeVar.isRightJoin) {
lookup = new OrderedLongHashSet();
}
conditions = rangeVar.joinConditions;
if (rangeVar.whereConditions[0].hasIndexCondition()) {
conditions = rangeVar.whereConditions;
}
}
public boolean isBeforeFirst() {
return isBeforeFirst;
}
public boolean next() {
if (session.abortTransaction) {
throw Error.error(ErrorCode.X_40000);
}
if (session.abortAction) {
throw Error.error(ErrorCode.X_40502);
}
while (condIndex < conditions.length) {
if (isBeforeFirst) {
isBeforeFirst = false;
initialiseIterator();
}
boolean result = findNext();
if (result) {
return true;
}
it.release();
it = RangeIterator.emptyRowIterator;
isBeforeFirst = true;
condIndex++;
}
condIndex = 0;
return false;
}
public void removeCurrent() {}
public void reset() {
it.release();
it = RangeIterator.emptyRowIterator;
isBeforeFirst = true;
condIndex = 0;
}
public int getRangePosition() {
return rangeVar.rangePosition;
}
/**
*/
protected void initialiseIterator() {
if (condIndex == 0) {
hasLeftOuterRow = rangeVar.isLeftJoin;
}
if (conditions[condIndex].isFalse) {
it = RowIterator.emptyRowIterator;
return;
}
rangeVar.rangeTable.materialiseCorrelated(session);
if (conditions[condIndex].indexCond == null) {
if (conditions[condIndex].reversed) {
it = conditions[condIndex].rangeIndex.lastRow(session,
store, rangeVar.indexDistinctCount, null);
} else {
it = conditions[condIndex].rangeIndex.firstRow(session,
store, null, rangeVar.indexDistinctCount, null);
}
} else {
getFirstRow();
if (!conditions[condIndex].isJoin) {
hasLeftOuterRow = false;
}
}
}
private void getFirstRow() {
if (currentJoinData == null
|| currentJoinData.length
< conditions[condIndex].indexedColumnCount) {
currentJoinData =
new Object[conditions[condIndex].indexedColumnCount];
}
int opType = conditions[condIndex].opType;
for (int i = 0; i < conditions[condIndex].indexedColumnCount;
i++) {
int range = 0;
int tempType = conditions[condIndex].opTypes[i];
if (tempType == OpTypes.IS_NULL || tempType == OpTypes.NOT
|| tempType == OpTypes.MAX) {
currentJoinData[i] = null;
continue;
}
Type valueType =
conditions[condIndex].indexCond[i].getRightNode()
.getDataType();
Object value =
conditions[condIndex].indexCond[i].getRightNode().getValue(
session);
Type targetType =
conditions[condIndex].indexCond[i].getLeftNode()
.getDataType();
if (i == 0 && value == null) {
it = RowIterator.emptyRowIterator;
return;
}
if (targetType != valueType) {
range = targetType.compareToTypeRange(value);
if (range == 0) {
if (targetType.typeComparisonGroup
!= valueType.typeComparisonGroup) {
value = targetType.convertToType(session, value,
valueType);
}
}
}
if (i == 0) {
int exprType =
conditions[condIndex].indexCond[0].getType();
if (range < 0) {
switch (exprType) {
case OpTypes.GREATER :
case OpTypes.GREATER_EQUAL :
case OpTypes.GREATER_EQUAL_PRE :
opType = OpTypes.NOT;
value = null;
break;
default :
it = RowIterator.emptyRowIterator;
return;
}
} else if (range > 0) {
switch (exprType) {
case OpTypes.NOT :
value = null;
break;
case OpTypes.SMALLER :
case OpTypes.SMALLER_EQUAL :
if (conditions[condIndex].reversed) {
opType = OpTypes.MAX;
value = null;
break;
}
// fall through
default :
it = RowIterator.emptyRowIterator;
return;
}
}
}
currentJoinData[i] = value;
}
it = conditions[condIndex].rangeIndex.findFirstRow(session, store,
currentJoinData, conditions[condIndex].indexedColumnCount,
rangeVar.indexDistinctCount, opType,
conditions[condIndex].reversed, null);
}
/**
* Advances to the next available value.
*
* @return true if a next value is available upon exit
*/
private boolean findNext() {
boolean result = false;
while (true) {
if (session.abortTransaction) {
throw Error.error(ErrorCode.X_40000);
}
if (session.abortAction) {
throw Error.error(ErrorCode.X_40502);
}
if (it.next()) {}
else {
it.release();
it = RangeIterator.emptyRowIterator;
break;
}
if (periodCondition != null) {
if (!periodCondition.testCondition(session)) {
continue;
}
}
if (filterCondition != null) {
if (!filterCondition.testCondition(session)) {
continue;
}
}
if (conditions[condIndex].terminalCondition != null) {
if (!conditions[condIndex].terminalCondition.testCondition(
session)) {
break;
}
}
if (conditions[condIndex].indexEndCondition != null) {
if (!conditions[condIndex].indexEndCondition.testCondition(
session)) {
if (!conditions[condIndex].isJoin) {
hasLeftOuterRow = false;
}
break;
}
}
if (joinConditions[condIndex].nonIndexCondition != null) {
if (!joinConditions[condIndex].nonIndexCondition
.testCondition(session)) {
continue;
}
}
if (whereConditions[condIndex].nonIndexCondition != null) {
if (!whereConditions[condIndex].nonIndexCondition
.testCondition(session)) {
hasLeftOuterRow = false;
addFoundRow();
continue;
}
}
Expression e = conditions[condIndex].excludeConditions;
if (e != null && e.testCondition(session)) {
continue;
}
addFoundRow();
hasLeftOuterRow = false;
return true;
}
it.release();
it = RangeIterator.emptyRowIterator;
if (hasLeftOuterRow && condIndex == conditions.length - 1) {
result =
(whereConditions[condIndex].nonIndexCondition == null
|| whereConditions[condIndex].nonIndexCondition
.testCondition(session));
hasLeftOuterRow = false;
}
return result;
}
private void addFoundRow() {
if (rangeVar.isRightJoin) {
long position = it.getRowId();
lookup.add(position);
}
}
}
public static class RangeIteratorRight extends RangeIteratorMain {
private RangeIteratorRight(Session session, RangeVariable rangeVar,
RangeIteratorMain main) {
super(session, rangeVar);
isFullIterator = true;
}
boolean isOnRightOuterRows;
public void setOnOuterRows() {
conditions = rangeVar.whereConditions;
isOnRightOuterRows = true;
hasLeftOuterRow = false;
condIndex = 0;
initialiseIterator();
}
public boolean next() {
if (isOnRightOuterRows) {
if (it == RangeIterator.emptyRowIterator) {
return false;
}
return findNextRight();
} else {
return super.next();
}
}
private boolean findNextRight() {
boolean result = false;
while (true) {
if (it.next()) {}
else {
it = RangeIterator.emptyRowIterator;
break;
}
if (conditions[condIndex].indexEndCondition != null
&& !conditions[condIndex].indexEndCondition
.testCondition(session)) {
break;
}
if (conditions[condIndex].nonIndexCondition != null
&& !conditions[condIndex].nonIndexCondition
.testCondition(session)) {
continue;
}
if (!lookupAndTest()) {
continue;
}
result = true;
break;
}
if (result) {
return true;
}
it.release();
return result;
}
private boolean lookupAndTest() {
long position = it.getRowId();
boolean result = !lookup.contains(position);
if (result) {
if (conditions[condIndex].nonIndexCondition != null) {
result =
conditions[condIndex].nonIndexCondition.testCondition(
session);
}
}
return result;
}
}
public static class RangeIteratorJoined extends RangeIteratorBase {
RangeIteratorMain[] rangeIterators;
int currentIndex = 0;
RangeIterator currentRange = null;
public RangeIteratorJoined(RangeIteratorMain[] rangeIterators) {
this.rangeIterators = rangeIterators;
isBeforeFirst = true;
}
public Row getCurrentRow() {
return currentRange.getCurrentRow();
}
public Object[] getCurrent() {
return currentRange.getCurrent();
}
public boolean isBeforeFirst() {
return isBeforeFirst;
}
public boolean next() {
while (currentIndex >= 0) {
currentRange = rangeIterators[currentIndex];
if (currentRange.next()) {
if (currentIndex < rangeIterators.length - 1) {
currentIndex++;
continue;
}
return true;
} else {
currentRange.reset();
currentIndex--;
}
}
currentRange = null;
for (int i = 0; i < rangeIterators.length; i++) {
rangeIterators[i].reset();
}
return false;
}
public void removeCurrent() {}
public void release() {
it.release();
for (int i = 0; i < rangeIterators.length; i++) {
rangeIterators[i].reset();
}
}
public void reset() {
super.reset();
for (int i = 0; i < rangeIterators.length; i++) {
rangeIterators[i].reset();
}
}
public int getRangePosition() {
return 0;
}
}
static final class RangeIteratorCheck implements RangeIterator {
final int rangePosition;
Object[] currentData;
RangeIteratorCheck() {
this.rangePosition = 0;
}
RangeIteratorCheck(int rangePosition) {
this.rangePosition = rangePosition;
}
public Object getField(int col) {
return currentData[col];
}
public boolean next() {
return false;
}
public Row getCurrentRow() {
return null;
}
public Object[] getCurrent() {
return currentData;
}
public boolean hasNext() {
return false;
}
public long getPos() {
return -1;
}
public int getStorageSize() {
return 0;
}
public void release() {}
public void removeCurrent() {}
public long getRowId() {
return 0L;
}
public boolean isBeforeFirst() {
return false;
}
public void setCurrent(Object[] data) {
this.currentData = data;
}
public void reset() {}
public int getRangePosition() {
return rangePosition;
}
}
public static class RangeVariableConditions {
final RangeVariable rangeVar;
Expression[] indexCond;
Expression[] indexEndCond;
int[] opTypes;
int[] opTypesEnd;
Expression indexEndCondition;
int indexedColumnCount;
Index rangeIndex;
final boolean isJoin;
Expression excludeConditions;
Expression nonIndexCondition;
Expression terminalCondition;
int opType;
int opTypeEnd;
boolean isFalse;
boolean reversed;
boolean hasIndex;
RangeVariableConditions(RangeVariable rangeVar, boolean isJoin) {
this.rangeVar = rangeVar;
this.isJoin = isJoin;
}
RangeVariableConditions(RangeVariableConditions base) {
this.rangeVar = base.rangeVar;
this.isJoin = base.isJoin;
nonIndexCondition = base.nonIndexCondition;
}
boolean hasIndexCondition() {
return indexedColumnCount > 0;
}
boolean hasIndex() {
return hasIndex;
}
void addCondition(Expression e) {
if (e == null) {
return;
}
if (e instanceof ExpressionLogical) {
if (((ExpressionLogical) e).isTerminal) {
terminalCondition = e;
}
}
nonIndexCondition =
ExpressionLogical.andExpressions(nonIndexCondition, e);
isFalse = Expression.EXPR_FALSE.equals(nonIndexCondition);
if (rangeIndex == null || rangeIndex.getColumnCount() == 0) {
return;
}
if (indexedColumnCount == 0) {
return;
}
if (e.getIndexableExpression(rangeVar) == null) {
return;
}
int colIndex = e.getLeftNode().getColumnIndex();
int[] indexCols = rangeIndex.getColumns();
switch (e.getType()) {
case OpTypes.GREATER :
case OpTypes.GREATER_EQUAL :
case OpTypes.GREATER_EQUAL_PRE : {
// replaces existing condition
if (opType == OpTypes.NOT) {
if (indexCols[indexedColumnCount - 1] == colIndex) {
nonIndexCondition =
ExpressionLogical.andExpressions(
nonIndexCondition,
indexCond[indexedColumnCount - 1]);
indexCond[indexedColumnCount - 1] = e;
opType = e.opType;
opTypes[indexedColumnCount - 1] = e.opType;
if (e.getType() == OpTypes.GREATER_EQUAL_PRE
&& indexedColumnCount == 1) {
indexEndCond[indexedColumnCount - 1] =
ExpressionLogical.andExpressions(
indexEndCond[indexedColumnCount - 1],
e.nodes[2]);
}
}
} else {
addToIndexConditions(e);
}
break;
}
case OpTypes.SMALLER :
case OpTypes.SMALLER_EQUAL : {
if (opType == OpTypes.GREATER
|| opType == OpTypes.GREATER_EQUAL
|| opType == OpTypes.GREATER_EQUAL_PRE
|| opType == OpTypes.NOT) {
if (opTypeEnd != OpTypes.MAX) {
break;
}
if (indexCols[indexedColumnCount - 1] == colIndex) {
indexEndCond[indexedColumnCount - 1] = e;
indexEndCondition =
ExpressionLogical.andExpressions(
indexEndCondition, e);
opTypeEnd = e.opType;
opTypesEnd[indexedColumnCount - 1] = e.opType;
}
} else {
addToIndexEndConditions(e);
}
break;
}
default :
}
}
private boolean addToIndexConditions(Expression e) {
if (opType == OpTypes.EQUAL || opType == OpTypes.IS_NULL) {
if (indexedColumnCount < rangeIndex.getColumnCount()) {
if (rangeIndex.getColumns()[indexedColumnCount]
== e.getLeftNode().getColumnIndex()) {
indexCond[indexedColumnCount] = e;
opType = e.opType;
opTypes[indexedColumnCount] = e.opType;
opTypeEnd = OpTypes.MAX;
opTypesEnd[indexedColumnCount] = OpTypes.MAX;
indexedColumnCount++;
return true;
}
}
}
return false;
}
private boolean addToIndexEndConditions(Expression e) {
if (opType == OpTypes.EQUAL || opType == OpTypes.IS_NULL) {
if (indexedColumnCount < rangeIndex.getColumnCount()) {
if (rangeIndex.getColumns()[indexedColumnCount]
== e.getLeftNode().getColumnIndex()) {
Expression condition =
ExpressionLogical.newNotNullCondition(
e.getLeftNode());
indexCond[indexedColumnCount] = condition;
indexEndCond[indexedColumnCount] = e;
indexEndCondition =
ExpressionLogical.andExpressions(indexEndCondition,
e);
opType = OpTypes.NOT;
opTypes[indexedColumnCount] = OpTypes.NOT;
opTypeEnd = e.opType;
opTypesEnd[indexedColumnCount] = e.opType;
indexedColumnCount++;
return true;
}
}
}
return false;
}
/**
*
* @param exprList has the same length as index column count
* @param index Index to use
* @param colCount number of columns searched
*/
void addIndexCondition(Expression[] exprList, Index index,
int colCount) {
int indexColCount = index.getColumnCount();
rangeIndex = index;
indexCond = new Expression[indexColCount];
indexEndCond = new Expression[indexColCount];
opTypes = new int[indexColCount];
opTypesEnd = new int[indexColCount];
opType = exprList[0].opType;
opTypes[0] = exprList[0].opType;
switch (opType) {
case OpTypes.NOT :
indexCond = exprList;
opTypeEnd = OpTypes.MAX;
opTypesEnd[0] = OpTypes.MAX;
break;
case OpTypes.GREATER :
case OpTypes.GREATER_EQUAL :
case OpTypes.GREATER_EQUAL_PRE :
indexCond = exprList;
if (exprList[0].getType() == OpTypes.GREATER_EQUAL_PRE) {
indexEndCond[0] = indexEndCondition =
exprList[0].nodes[2];
}
opTypeEnd = OpTypes.MAX;
opTypesEnd[0] = OpTypes.MAX;
break;
case OpTypes.SMALLER :
case OpTypes.SMALLER_EQUAL : {
Expression e = exprList[0].getLeftNode();
e = new ExpressionLogical(OpTypes.IS_NULL, e);
e = new ExpressionLogical(OpTypes.NOT, e);
indexCond[0] = e;
indexEndCond[0] = indexEndCondition = exprList[0];
opTypeEnd = opType;
opTypesEnd[0] = opType;
opType = OpTypes.NOT;
opTypes[0] = OpTypes.NOT;
break;
}
case OpTypes.IS_NULL :
case OpTypes.EQUAL : {
indexCond = exprList;
for (int i = 0; i < colCount; i++) {
Expression e = exprList[i];
indexEndCond[i] = e;
indexEndCondition =
ExpressionLogical.andExpressions(indexEndCondition,
e);
opType = e.opType;
opTypes[i] = e.opType;
opTypesEnd[i] = e.opType;
}
opTypeEnd = opType;
break;
}
default :
throw Error.runtimeError(ErrorCode.U_S0500,
"RangeVariable");
}
indexedColumnCount = colCount;
hasIndex = true;
}
private void reverseIndexCondition() {
if (indexedColumnCount == 0) {
reversed = true;
return;
}
if (opType == OpTypes.EQUAL || opType == OpTypes.IS_NULL) {
//
} else {
indexEndCondition = null;
Expression[] temp = indexCond;
indexCond = indexEndCond;
indexEndCond = temp;
int[] temptypes = opTypes;
opTypes = opTypesEnd;
opTypesEnd = temptypes;
for (int i = 0; i < indexedColumnCount; i++) {
Expression e = indexEndCond[i];
indexEndCondition =
ExpressionLogical.andExpressions(indexEndCondition, e);
}
if (indexedColumnCount > 1
&& opTypes[indexedColumnCount - 1] == OpTypes.MAX) {
indexedColumnCount--;
opTypes[indexedColumnCount] = 0;
opTypesEnd[indexedColumnCount] = 0;
}
opType = opTypes[indexedColumnCount - 1];
opTypeEnd = opTypesEnd[indexedColumnCount - 1];
}
reversed = true;
}
String describe(Session session, int blanks) {
StringBuilder sb = new StringBuilder();
StringBuilder b = new StringBuilder(blanks);
for (int i = 0; i < blanks; i++) {
b.append(' ');
}
sb.append("index=").append(rangeIndex.getName().name).append("\n");
if (hasIndexCondition()) {
if (indexedColumnCount > 0) {
sb.append(b).append("start conditions=[");
for (int j = 0; j < indexedColumnCount; j++) {
if (indexCond != null && indexCond[j] != null) {
sb.append(indexCond[j].describe(session, blanks));
}
}
sb.append("]\n");
}
if (this.opTypeEnd != OpTypes.EQUAL
&& indexEndCondition != null) {
String temp = indexEndCondition.describe(session, blanks);
sb.append(b).append("end condition=[").append(temp).append(
"]\n");
}
}
if (nonIndexCondition != null) {
String temp = nonIndexCondition.describe(session, blanks);
sb.append(b).append("other condition=[").append(temp).append(
"]\n");
}
return sb.toString();
}
private void replaceColumnReferences(Session session,
RangeVariable range,
Expression[] list) {
if (indexCond != null) {
for (int i = 0; i < indexCond.length; i++) {
if (indexCond[i] != null) {
indexCond[i] =
indexCond[i].replaceColumnReferences(session,
range, list);
}
}
}
if (indexEndCond != null) {
for (int i = 0; i < indexEndCond.length; i++) {
if (indexEndCond[i] != null) {
indexEndCond[i] =
indexEndCond[i].replaceColumnReferences(session,
range, list);
}
}
}
if (indexEndCondition != null) {
indexEndCondition =
indexEndCondition.replaceColumnReferences(session, range,
list);
}
if (excludeConditions != null) {
excludeConditions =
excludeConditions.replaceColumnReferences(session, range,
list);
}
if (nonIndexCondition != null) {
nonIndexCondition =
nonIndexCondition.replaceColumnReferences(session, range,
list);
}
if (terminalCondition != null) {
terminalCondition =
terminalCondition.replaceColumnReferences(session, range,
list);
}
}
private void replaceExpressions(OrderedHashSet expressions,
int resultRangePosition) {
if (indexCond != null) {
for (int i = 0; i < indexCond.length; i++) {
if (indexCond[i] != null) {
indexCond[i] = indexCond[i].replaceExpressions(
expressions, resultRangePosition);
}
}
}
if (indexEndCond != null) {
for (int i = 0; i < indexEndCond.length; i++) {
if (indexEndCond[i] != null) {
indexEndCond[i] = indexEndCond[i].replaceExpressions(
expressions, resultRangePosition);
}
}
}
if (indexEndCondition != null) {
indexEndCondition =
indexEndCondition.replaceExpressions(expressions,
resultRangePosition);
}
if (excludeConditions != null) {
excludeConditions =
excludeConditions.replaceExpressions(expressions,
resultRangePosition);
}
if (nonIndexCondition != null) {
nonIndexCondition =
nonIndexCondition.replaceExpressions(expressions,
resultRangePosition);
}
if (terminalCondition != null) {
terminalCondition =
terminalCondition.replaceExpressions(expressions,
resultRangePosition);
}
}
}
}