You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by sk...@apache.org on 2019/08/19 22:25:23 UTC
[phoenix] branch 4.x-HBase-1.3 updated: PHOENIX-5390:Changing
anonymous inner classes
This is an automated email from the ASF dual-hosted git repository.
skadam pushed a commit to branch 4.x-HBase-1.3
in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/4.x-HBase-1.3 by this push:
new c38fb7c PHOENIX-5390:Changing anonymous inner classes
c38fb7c is described below
commit c38fb7c38e294358fd98c1c57b2ee661f289dd6f
Author: Neha <ne...@salesforce.com>
AuthorDate: Fri Jul 26 11:43:01 2019 -0700
PHOENIX-5390:Changing anonymous inner classes
Adding nit changes
Signed-off-by: s.kadam <sk...@apache.org>
---
.../org/apache/phoenix/execute/CorrelatePlan.java | 194 +++++++++++----------
.../expression/function/InvertFunction.java | 88 +++++-----
.../expression/function/PrefixFunction.java | 110 ++++++------
.../phoenix/iterate/OrderedResultIterator.java | 100 ++++++-----
.../apache/phoenix/optimize/QueryOptimizer.java | 116 ++++++------
5 files changed, 323 insertions(+), 285 deletions(-)
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/CorrelatePlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/CorrelatePlan.java
index b5491aa..68b1505 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/CorrelatePlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/CorrelatePlan.java
@@ -56,6 +56,7 @@ public class CorrelatePlan extends DelegateQueryPlan {
private final KeyValueSchema rhsSchema;
private final int rhsFieldPosition;
+
public CorrelatePlan(QueryPlan lhs, QueryPlan rhs, String variableId,
JoinType joinType, boolean isSingleValueOnly,
RuntimeContext runtimeContext, PTable joinedTable,
@@ -104,99 +105,7 @@ public class CorrelatePlan extends DelegateQueryPlan {
@Override
public ResultIterator iterator(final ParallelScanGrouper scanGrouper, final Scan scan)
throws SQLException {
- return new ResultIterator() {
- private final ValueBitSet destBitSet = ValueBitSet.newInstance(joinedSchema);
- private final ValueBitSet lhsBitSet = ValueBitSet.newInstance(lhsSchema);
- private final ValueBitSet rhsBitSet =
- (joinType == JoinType.Semi || joinType == JoinType.Anti) ?
- ValueBitSet.EMPTY_VALUE_BITSET
- : ValueBitSet.newInstance(rhsSchema);
- private final ResultIterator iter = delegate.iterator(scanGrouper, scan);
- private ResultIterator rhsIter = null;
- private Tuple current = null;
- private boolean closed = false;
-
- @Override
- public void close() throws SQLException {
- if (!closed) {
- closed = true;
- iter.close();
- if (rhsIter != null) {
- rhsIter.close();
- }
- }
- }
-
- @Override
- public Tuple next() throws SQLException {
- if (closed)
- return null;
-
- Tuple rhsCurrent = null;
- if (rhsIter != null) {
- rhsCurrent = rhsIter.next();
- if (rhsCurrent == null) {
- rhsIter.close();
- rhsIter = null;
- } else if (isSingleValueOnly) {
- throw new SQLExceptionInfo.Builder(SQLExceptionCode.SINGLE_ROW_SUBQUERY_RETURNS_MULTIPLE_ROWS).build().buildException();
- }
- }
- while (rhsIter == null) {
- current = iter.next();
- if (current == null) {
- close();
- return null;
- }
- runtimeContext.setCorrelateVariableValue(variableId, current);
- rhsIter = rhs.iterator();
- rhsCurrent = rhsIter.next();
- if ((rhsCurrent == null && (joinType == JoinType.Inner || joinType == JoinType.Semi))
- || (rhsCurrent != null && joinType == JoinType.Anti)) {
- rhsIter.close();
- rhsIter = null;
- }
- }
-
- Tuple joined;
- try {
- joined = rhsBitSet == ValueBitSet.EMPTY_VALUE_BITSET ?
- current : TupleProjector.mergeProjectedValue(
- convertLhs(current), destBitSet,
- rhsCurrent, rhsBitSet, rhsFieldPosition, true);
- } catch (IOException e) {
- throw new SQLException(e);
- }
-
- if ((joinType == JoinType.Semi || rhsCurrent == null) && rhsIter != null) {
- rhsIter.close();
- rhsIter = null;
- }
-
- return joined;
- }
-
- @Override
- public void explain(List<String> planSteps) {
- }
-
- private ProjectedValueTuple convertLhs(Tuple lhs) throws IOException {
- ProjectedValueTuple t;
- if (lhs instanceof ProjectedValueTuple) {
- t = (ProjectedValueTuple) lhs;
- } else {
- ImmutableBytesWritable ptr = getContext().getTempPtr();
- TupleProjector.decodeProjectedValue(lhs, ptr);
- lhsBitSet.clear();
- lhsBitSet.or(ptr);
- int bitSetLen = lhsBitSet.getEstimatedLength();
- t = new ProjectedValueTuple(lhs, lhs.getValue(0).getTimestamp(),
- ptr.get(), ptr.getOffset(), ptr.getLength(), bitSetLen);
-
- }
- return t;
- }
- };
+ return new CorrelateResultIterator(scanGrouper, scan) ;
}
@Override
@@ -227,4 +136,103 @@ public class CorrelatePlan extends DelegateQueryPlan {
return cost.plus(lhsCost).plus(rhs.getCost());
}
+ private class CorrelateResultIterator implements ResultIterator {
+ private final ValueBitSet destBitSet = ValueBitSet.newInstance(joinedSchema);
+ private final ValueBitSet lhsBitSet = ValueBitSet.newInstance(lhsSchema);
+ private final ValueBitSet rhsBitSet =
+ (joinType == JoinType.Semi || joinType == JoinType.Anti) ?
+ ValueBitSet.EMPTY_VALUE_BITSET
+ : ValueBitSet.newInstance(rhsSchema);
+ private final ResultIterator iter;
+ private ResultIterator rhsIter = null;
+ private Tuple current = null;
+ private boolean closed = false;
+
+ private CorrelateResultIterator(ParallelScanGrouper scanGrouper, Scan scan)
+ throws SQLException {
+ iter = delegate.iterator(scanGrouper, scan);
+ }
+
+ @Override
+ public void close() throws SQLException {
+ if (!closed) {
+ closed = true;
+ iter.close();
+ if (rhsIter != null) {
+ rhsIter.close();
+ }
+ }
+ }
+
+ @Override
+ public Tuple next() throws SQLException {
+ if (closed)
+ return null;
+
+ Tuple rhsCurrent = null;
+ if (rhsIter != null) {
+ rhsCurrent = rhsIter.next();
+ if (rhsCurrent == null) {
+ rhsIter.close();
+ rhsIter = null;
+ } else if (isSingleValueOnly) {
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.SINGLE_ROW_SUBQUERY_RETURNS_MULTIPLE_ROWS)
+ .build().buildException();
+ }
+ }
+ while (rhsIter == null) {
+ current = iter.next();
+ if (current == null) {
+ close();
+ return null;
+ }
+ runtimeContext.setCorrelateVariableValue(variableId, current);
+ rhsIter = rhs.iterator();
+ rhsCurrent = rhsIter.next();
+ if ((rhsCurrent == null && (joinType == JoinType.Inner || joinType == JoinType.Semi))
+ || (rhsCurrent != null && joinType == JoinType.Anti)) {
+ rhsIter.close();
+ rhsIter = null;
+ }
+ }
+
+ Tuple joined;
+ try {
+ joined = rhsBitSet == ValueBitSet.EMPTY_VALUE_BITSET ?
+ current : TupleProjector.mergeProjectedValue(
+ convertLhs(current), destBitSet,
+ rhsCurrent, rhsBitSet, rhsFieldPosition, true);
+ } catch (IOException e) {
+ throw new SQLException(e);
+ }
+
+ if ((joinType == JoinType.Semi || rhsCurrent == null) && rhsIter != null) {
+ rhsIter.close();
+ rhsIter = null;
+ }
+
+ return joined;
+ }
+
+ @Override
+ public void explain(List<String> planSteps) { }
+
+ private ProjectedValueTuple convertLhs(Tuple lhs) throws IOException {
+ ProjectedValueTuple tuple;
+ if (lhs instanceof ProjectedValueTuple) {
+ tuple = (ProjectedValueTuple) lhs;
+ } else {
+ ImmutableBytesWritable ptr = getContext().getTempPtr();
+ TupleProjector.decodeProjectedValue(lhs, ptr);
+ lhsBitSet.clear();
+ lhsBitSet.or(ptr);
+ int bitSetLen = lhsBitSet.getEstimatedLength();
+ tuple = new ProjectedValueTuple(lhs, lhs.getValue(0).getTimestamp(),
+ ptr.get(), ptr.getOffset(), ptr.getLength(), bitSetLen);
+
+ }
+ return tuple;
+ }
+ }
+
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/InvertFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/InvertFunction.java
index 8ef5914..038221d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/InvertFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/InvertFunction.java
@@ -91,46 +91,7 @@ public class InvertFunction extends ScalarFunction {
*/
@Override
public KeyPart newKeyPart(final KeyPart childPart) {
- return new KeyPart() {
-
- @Override
- public KeyRange getKeyRange(CompareOp op, Expression rhs) {
- KeyRange range = childPart.getKeyRange(op, rhs);
- byte[] lower = range.getLowerRange();
- if (!range.lowerUnbound()) {
- lower = SortOrder.invert(lower, 0, lower.length);
- }
- byte[] upper;
- if (range.isSingleKey()) {
- upper = lower;
- } else {
- upper = range.getUpperRange();
- if (!range.upperUnbound()) {
- upper = SortOrder.invert(upper, 0, upper.length);
- }
- }
- range = KeyRange.getKeyRange(lower, range.isLowerInclusive(), upper, range.isUpperInclusive());
- if (getColumn().getSortOrder() == SortOrder.DESC) {
- range = range.invert();
- }
- return range;
- }
-
- @Override
- public List<Expression> getExtractNodes() {
- return childPart.getExtractNodes();
- }
-
- @Override
- public PColumn getColumn() {
- return childPart.getColumn();
- }
-
- @Override
- public PTable getTable() {
- return childPart.getTable();
- }
- };
+ return new InvertKeyPart(childPart);
}
@Override
@@ -141,4 +102,51 @@ public class InvertFunction extends ScalarFunction {
private Expression getChildExpression() {
return children.get(0);
}
+
+ private static class InvertKeyPart implements KeyPart {
+
+ private final KeyPart childPart;
+
+ public InvertKeyPart(KeyPart childPart) {
+ this.childPart = childPart;
+ }
+
+ @Override
+ public KeyRange getKeyRange(CompareOp op, Expression rhs) {
+ KeyRange range = childPart.getKeyRange(op, rhs);
+ byte[] lower = range.getLowerRange();
+ if (!range.lowerUnbound()) {
+ lower = SortOrder.invert(lower, 0, lower.length);
+ }
+ byte[] upper;
+ if (range.isSingleKey()) {
+ upper = lower;
+ } else {
+ upper = range.getUpperRange();
+ if (!range.upperUnbound()) {
+ upper = SortOrder.invert(upper, 0, upper.length);
+ }
+ }
+ range = KeyRange.getKeyRange(lower, range.isLowerInclusive(), upper, range.isUpperInclusive());
+ if (getColumn().getSortOrder() == SortOrder.DESC) {
+ range = range.invert();
+ }
+ return range;
+ }
+
+ @Override
+ public List<Expression> getExtractNodes() {
+ return childPart.getExtractNodes();
+ }
+
+ @Override
+ public PColumn getColumn() {
+ return childPart.getColumn();
+ }
+
+ @Override
+ public PTable getTable() {
+ return childPart.getTable();
+ }
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/PrefixFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/PrefixFunction.java
index ff3e74d..b09c14d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/PrefixFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/PrefixFunction.java
@@ -21,7 +21,6 @@ package org.apache.phoenix.expression.function;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.phoenix.compile.KeyPart;
import org.apache.phoenix.expression.Expression;
@@ -34,8 +33,7 @@ import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.util.ByteUtil;
abstract public class PrefixFunction extends ScalarFunction {
- public PrefixFunction() {
- }
+ public PrefixFunction() { }
public PrefixFunction(List<Expression> children) {
super(children);
@@ -52,26 +50,36 @@ abstract public class PrefixFunction extends ScalarFunction {
@Override
public KeyPart newKeyPart(final KeyPart childPart) {
- return new KeyPart() {
- private final List<Expression> extractNodes = extractNode() ? Collections.<Expression>singletonList(PrefixFunction.this) : Collections.<Expression>emptyList();
+ return new PrefixKeyPart(childPart);
+ }
- @Override
- public PColumn getColumn() {
- return childPart.getColumn();
- }
+ private class PrefixKeyPart implements KeyPart {
+ private final List<Expression> extractNodes = extractNode() ?
+ Collections.<Expression>singletonList(PrefixFunction.this)
+ : Collections.<Expression>emptyList();
+ private final KeyPart childPart;
- @Override
- public List<Expression> getExtractNodes() {
- return extractNodes;
- }
+ PrefixKeyPart(KeyPart childPart) {
+ this.childPart = childPart;
+ }
+
+ @Override
+ public PColumn getColumn() {
+ return childPart.getColumn();
+ }
+
+ @Override
+ public List<Expression> getExtractNodes() {
+ return extractNodes;
+ }
- @Override
- public KeyRange getKeyRange(CompareOp op, Expression rhs) {
- byte[] lowerRange = KeyRange.UNBOUND;
- byte[] upperRange = KeyRange.UNBOUND;
- boolean lowerInclusive = true;
- PDataType type = getColumn().getDataType();
- switch (op) {
+ @Override
+ public KeyRange getKeyRange(CompareOp op, Expression rhs) {
+ byte[] lowerRange = KeyRange.UNBOUND;
+ byte[] upperRange = KeyRange.UNBOUND;
+ boolean lowerInclusive = true;
+ PDataType type = getColumn().getDataType();
+ switch (op) {
case EQUAL:
lowerRange = evaluateExpression(rhs);
upperRange = ByteUtil.nextKey(lowerRange);
@@ -85,44 +93,42 @@ abstract public class PrefixFunction extends ScalarFunction {
break;
default:
return childPart.getKeyRange(op, rhs);
- }
- PColumn column = getColumn();
- Integer length = column.getMaxLength();
- if (type.isFixedWidth()) {
- if (length != null) { // Sanity check - shouldn't be necessary
- // Don't pad based on current sort order, but instead use our
- // minimum byte as otherwise we'll end up skipping rows in
- // the case of descending, since rows with more padding appear
- // *after* rows with no padding.
- if (lowerRange != KeyRange.UNBOUND) {
- lowerRange = type.pad(lowerRange, length, SortOrder.ASC);
- }
- if (upperRange != KeyRange.UNBOUND) {
- upperRange = type.pad(upperRange, length, SortOrder.ASC);
- }
- }
- } else if (column.getSortOrder() == SortOrder.DESC && getTable().rowKeyOrderOptimizable()) {
- // Append a zero byte if descending since a \xFF byte will be appended to the lowerRange
- // causing rows to be skipped that should be included. For example, with rows 'ab', 'a',
- // a lowerRange of 'a\xFF' would skip 'ab', while 'a\x00\xFF' would not.
+ }
+ PColumn column = getColumn();
+ Integer length = column.getMaxLength();
+ if (type.isFixedWidth()) {
+ if (length != null) { // Sanity check - shouldn't be necessary
+ // Don't pad based on current sort order, but instead use our
+ // minimum byte as otherwise we'll end up skipping rows in
+ // the case of descending, since rows with more padding appear
+ // *after* rows with no padding.
if (lowerRange != KeyRange.UNBOUND) {
- lowerRange = Arrays.copyOf(lowerRange, lowerRange.length+1);
- lowerRange[lowerRange.length-1] = QueryConstants.SEPARATOR_BYTE;
+ lowerRange = type.pad(lowerRange, length, SortOrder.ASC);
+ }
+ if (upperRange != KeyRange.UNBOUND) {
+ upperRange = type.pad(upperRange, length, SortOrder.ASC);
}
}
- KeyRange range = KeyRange.getKeyRange(lowerRange, lowerInclusive, upperRange, false);
- if (column.getSortOrder() == SortOrder.DESC) {
- range = range.invert();
+ } else if (column.getSortOrder() == SortOrder.DESC && getTable().rowKeyOrderOptimizable()) {
+ // Append a zero byte if descending since a \xFF byte will be appended to the lowerRange
+ // causing rows to be skipped that should be included. For example, with rows 'ab', 'a',
+ // a lowerRange of 'a\xFF' would skip 'ab', while 'a\x00\xFF' would not.
+ if (lowerRange != KeyRange.UNBOUND) {
+ lowerRange = Arrays.copyOf(lowerRange, lowerRange.length+1);
+ lowerRange[lowerRange.length-1] = QueryConstants.SEPARATOR_BYTE;
}
- return range;
}
-
- @Override
- public PTable getTable() {
- return childPart.getTable();
+ KeyRange range = KeyRange.getKeyRange(lowerRange, lowerInclusive, upperRange, false);
+ if (column.getSortOrder() == SortOrder.DESC) {
+ range = range.invert();
}
- };
- }
+ return range;
+ }
+ @Override
+ public PTable getTable() {
+ return childPart.getTable();
+ }
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedResultIterator.java b/phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedResultIterator.java
index 212410c..5430226 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedResultIterator.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedResultIterator.java
@@ -257,52 +257,7 @@ public class OrderedResultIterator implements PeekingResultIterator {
final SizeAwareQueue<ResultEntry> queueEntries =
PhoenixQueues.newResultEntrySortedQueue(comparator, limit, spoolingEnabled,
thresholdBytes);
- resultIterator = new PeekingResultIterator() {
- int count = 0;
-
- @Override
- public Tuple next() throws SQLException {
- ResultEntry entry = queueEntries.poll();
- while (entry != null && offset != null && count < offset) {
- count++;
- if (entry.getResult() == null) { return null; }
- entry = queueEntries.poll();
- }
- if (entry == null || (limit != null && count++ > limit)) {
- resultIterator.close();
- resultIterator = PeekingResultIterator.EMPTY_ITERATOR;
- return null;
- }
- return entry.getResult();
- }
-
- @Override
- public Tuple peek() throws SQLException {
- ResultEntry entry = queueEntries.peek();
- while (entry != null && offset != null && count < offset) {
- entry = queueEntries.poll();
- count++;
- if (entry == null) { return null; }
- }
- if (limit != null && count > limit) { return null; }
- entry = queueEntries.peek();
- if (entry == null) { return null; }
- return entry.getResult();
- }
-
- @Override
- public void explain(List<String> planSteps) {
- }
-
- @Override
- public void close() throws SQLException {
- try {
- queueEntries.close();
- } catch (IOException e) {
- throw new SQLException(e);
- }
- }
- };
+ resultIterator = new RecordPeekingResultIterator(queueEntries);
for (Tuple result = delegate.next(); result != null; result = delegate.next()) {
int pos = 0;
ImmutableBytesWritable[] sortKeys = new ImmutableBytesWritable[numSortKeys];
@@ -356,4 +311,57 @@ public class OrderedResultIterator implements PeekingResultIterator {
+ ", resultIterator=" + resultIterator + ", byteSize="
+ byteSize + "]";
}
+
+ private class RecordPeekingResultIterator implements PeekingResultIterator {
+ int count = 0;
+
+ private SizeAwareQueue<ResultEntry> queueEntries;
+
+ RecordPeekingResultIterator(SizeAwareQueue<ResultEntry> queueEntries){
+ this.queueEntries = queueEntries;
+ }
+
+ @Override
+ public Tuple next() throws SQLException {
+ ResultEntry entry = queueEntries.poll();
+ while (entry != null && offset != null && count < offset) {
+ count++;
+ if (entry.getResult() == null) { return null; }
+ entry = queueEntries.poll();
+ }
+ if (entry == null || (limit != null && count++ > limit)) {
+ resultIterator.close();
+ resultIterator = PeekingResultIterator.EMPTY_ITERATOR;
+ return null;
+ }
+ return entry.getResult();
+ }
+
+ @Override
+ public Tuple peek() throws SQLException {
+ ResultEntry entry = queueEntries.peek();
+ while (entry != null && offset != null && count < offset) {
+ entry = queueEntries.poll();
+ count++;
+ if (entry == null) { return null; }
+ }
+ if (limit != null && count > limit) { return null; }
+ entry = queueEntries.peek();
+ if (entry == null) { return null; }
+ return entry.getResult();
+ }
+
+ @Override
+ public void explain(List<String> planSteps) {
+ }
+
+ @Override
+ public void close() throws SQLException {
+ try {
+ queueEntries.close();
+ } catch (IOException e) {
+ throw new SQLException(e);
+ }
+ }
+ }
}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java b/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
index 45c7e7d..7cad7ec 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
@@ -590,71 +590,79 @@ public class QueryOptimizer {
final PhoenixConnection connection, final ColumnResolver resolver,
final SelectStatement select, final Map<TableRef, TableRef> replacement) throws SQLException {
TableNode from = select.getFrom();
- TableNode newFrom = from.accept(new TableNodeVisitor<TableNode>() {
- private TableRef resolveTable(String alias, TableName name) throws SQLException {
- if (alias != null)
- return resolver.resolveTable(null, alias);
+ TableNode newFrom = from.accept(new QueryOptimizerTableNode(resolver, replacement));
+ if (from == newFrom) {
+ return select;
+ }
- return resolver.resolveTable(name.getSchemaName(), name.getTableName());
- }
+ SelectStatement indexSelect = IndexStatementRewriter.translate(FACTORY.select(select, newFrom), resolver, replacement);
+ for (TableRef indexTableRef : replacement.values()) {
+ // replace expressions with corresponding matching columns for functional indexes
+ indexSelect = ParseNodeRewriter.rewrite(indexSelect, new IndexExpressionParseNodeRewriter(indexTableRef.getTable(), indexTableRef.getTableAlias(), connection, indexSelect.getUdfParseNodes()));
+ }
- private TableName getReplacedTableName(TableRef tableRef) {
- String schemaName = tableRef.getTable().getSchemaName().getString();
- return TableName.create(schemaName.length() == 0 ? null : schemaName, tableRef.getTable().getTableName().getString());
- }
+ return indexSelect;
+ }
+ private static class QueryOptimizerTableNode implements TableNodeVisitor<TableNode> {
+ private final ColumnResolver resolver;
+ private final Map<TableRef, TableRef> replacement;
- @Override
- public TableNode visit(BindTableNode boundTableNode) throws SQLException {
- TableRef tableRef = resolveTable(boundTableNode.getAlias(), boundTableNode.getName());
- TableRef replaceRef = replacement.get(tableRef);
- if (replaceRef == null)
- return boundTableNode;
-
- String alias = boundTableNode.getAlias();
- return FACTORY.bindTable(alias == null ? null : '"' + alias + '"', getReplacedTableName(replaceRef));
- }
+ QueryOptimizerTableNode (ColumnResolver resolver, final Map<TableRef, TableRef> replacement){
+ this.resolver = resolver;
+ this.replacement = replacement;
+ }
- @Override
- public TableNode visit(JoinTableNode joinNode) throws SQLException {
- TableNode lhs = joinNode.getLHS();
- TableNode rhs = joinNode.getRHS();
- TableNode lhsReplace = lhs.accept(this);
- TableNode rhsReplace = rhs.accept(this);
- if (lhs == lhsReplace && rhs == rhsReplace)
- return joinNode;
-
- return FACTORY.join(joinNode.getType(), lhsReplace, rhsReplace, joinNode.getOnNode(), joinNode.isSingleValueOnly());
- }
+ private TableRef resolveTable(String alias, TableName name) throws SQLException {
+ if (alias != null)
+ return resolver.resolveTable(null, alias);
- @Override
- public TableNode visit(NamedTableNode namedTableNode)
- throws SQLException {
- TableRef tableRef = resolveTable(namedTableNode.getAlias(), namedTableNode.getName());
- TableRef replaceRef = replacement.get(tableRef);
- if (replaceRef == null)
- return namedTableNode;
+ return resolver.resolveTable(name.getSchemaName(), name.getTableName());
+ }
- String alias = namedTableNode.getAlias();
- return FACTORY.namedTable(alias == null ? null : '"' + alias + '"', getReplacedTableName(replaceRef), namedTableNode.getDynamicColumns(), namedTableNode.getTableSamplingRate());
- }
+ private TableName getReplacedTableName(TableRef tableRef) {
+ String schemaName = tableRef.getTable().getSchemaName().getString();
+ return TableName.create(schemaName.length() == 0 ? null : schemaName, tableRef.getTable().getTableName().getString());
+ }
- @Override
- public TableNode visit(DerivedTableNode subselectNode)
- throws SQLException {
- return subselectNode;
- }
- });
+ @Override
+ public TableNode visit(BindTableNode boundTableNode) throws SQLException {
+ TableRef tableRef = resolveTable(boundTableNode.getAlias(), boundTableNode.getName());
+ TableRef replaceRef = replacement.get(tableRef);
+ if (replaceRef == null)
+ return boundTableNode;
+
+ String alias = boundTableNode.getAlias();
+ return FACTORY.bindTable(alias == null ? null : '"' + alias + '"', getReplacedTableName(replaceRef));
+ }
- if (from == newFrom) {
- return select;
+ @Override
+ public TableNode visit(JoinTableNode joinNode) throws SQLException {
+ TableNode lhs = joinNode.getLHS();
+ TableNode rhs = joinNode.getRHS();
+ TableNode lhsReplace = lhs.accept(this);
+ TableNode rhsReplace = rhs.accept(this);
+ if (lhs == lhsReplace && rhs == rhsReplace)
+ return joinNode;
+
+ return FACTORY.join(joinNode.getType(), lhsReplace, rhsReplace, joinNode.getOnNode(), joinNode.isSingleValueOnly());
}
- SelectStatement indexSelect = IndexStatementRewriter.translate(FACTORY.select(select, newFrom), resolver, replacement);
- for (TableRef indexTableRef : replacement.values()) {
- // replace expressions with corresponding matching columns for functional indexes
- indexSelect = ParseNodeRewriter.rewrite(indexSelect, new IndexExpressionParseNodeRewriter(indexTableRef.getTable(), indexTableRef.getTableAlias(), connection, indexSelect.getUdfParseNodes()));
+ @Override
+ public TableNode visit(NamedTableNode namedTableNode)
+ throws SQLException {
+ TableRef tableRef = resolveTable(namedTableNode.getAlias(), namedTableNode.getName());
+ TableRef replaceRef = replacement.get(tableRef);
+ if (replaceRef == null)
+ return namedTableNode;
+
+ String alias = namedTableNode.getAlias();
+ return FACTORY.namedTable(alias == null ? null : '"' + alias + '"', getReplacedTableName(replaceRef), namedTableNode.getDynamicColumns(), namedTableNode.getTableSamplingRate());
}
- return indexSelect;
+ @Override
+ public TableNode visit(DerivedTableNode subselectNode)
+ throws SQLException {
+ return subselectNode;
+ }
}
}