You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ma...@apache.org on 2015/03/04 23:41:18 UTC
[43/50] [abbrv] phoenix git commit: PHOENIX-1489 Access column values
positionally from client
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
index 27fe0f9..e84ca2a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
@@ -62,6 +62,7 @@ import org.apache.phoenix.parse.TableName;
import org.apache.phoenix.parse.TableWildcardParseNode;
import org.apache.phoenix.parse.WildcardParseNode;
import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.schema.AmbiguousColumnException;
import org.apache.phoenix.schema.ArgumentTypeMismatchException;
import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
import org.apache.phoenix.schema.ColumnNotFoundException;
@@ -144,12 +145,21 @@ public class ProjectionCompiler {
}
ColumnRef ref = new ColumnRef(tableRef,i);
String colName = ref.getColumn().getName().getString();
+ String tableAlias = tableRef.getTableAlias();
if (resolveColumn) {
- if (tableRef.getTableAlias() != null) {
- ref = resolver.resolveColumn(null, tableRef.getTableAlias(), colName);
- } else {
- String schemaName = table.getSchemaName().getString();
- ref = resolver.resolveColumn(schemaName.length() == 0 ? null : schemaName, table.getTableName().getString(), colName);
+ try {
+ if (tableAlias != null) {
+ ref = resolver.resolveColumn(null, tableAlias, colName);
+ } else {
+ String schemaName = table.getSchemaName().getString();
+ ref = resolver.resolveColumn(schemaName.length() == 0 ? null : schemaName, table.getTableName().getString(), colName);
+ }
+ } catch (AmbiguousColumnException e) {
+ if (column.getFamilyName() != null) {
+ ref = resolver.resolveColumn(tableAlias != null ? tableAlias : table.getTableName().getString(), column.getFamilyName().getString(), colName);
+ } else {
+ throw e;
+ }
}
}
Expression expression = ref.newColumnExpression();
@@ -219,12 +229,21 @@ public class ProjectionCompiler {
}
}
String colName = tableColumn.getName().getString();
+ String tableAlias = tableRef.getTableAlias();
if (resolveColumn) {
- if (tableRef.getTableAlias() != null) {
- ref = resolver.resolveColumn(null, tableRef.getTableAlias(), indexColName);
- } else {
- String schemaName = index.getSchemaName().getString();
- ref = resolver.resolveColumn(schemaName.length() == 0 ? null : schemaName, index.getTableName().getString(), indexColName);
+ try {
+ if (tableAlias != null) {
+ ref = resolver.resolveColumn(null, tableAlias, indexColName);
+ } else {
+ String schemaName = index.getSchemaName().getString();
+ ref = resolver.resolveColumn(schemaName.length() == 0 ? null : schemaName, index.getTableName().getString(), indexColName);
+ }
+ } catch (AmbiguousColumnException e) {
+ if (indexColumn.getFamilyName() != null) {
+ ref = resolver.resolveColumn(tableAlias != null ? tableAlias : index.getTableName().getString(), indexColumn.getFamilyName().getString(), indexColName);
+ } else {
+ throw e;
+ }
}
}
Expression expression = ref.newColumnExpression();
@@ -238,11 +257,14 @@ public class ProjectionCompiler {
}
}
- private static void projectTableColumnFamily(StatementContext context, String cfName, TableRef tableRef, List<Expression> projectedExpressions, List<ExpressionProjector> projectedColumns) throws SQLException {
+ private static void projectTableColumnFamily(StatementContext context, String cfName, TableRef tableRef, boolean resolveColumn, List<Expression> projectedExpressions, List<ExpressionProjector> projectedColumns) throws SQLException {
PTable table = tableRef.getTable();
PColumnFamily pfamily = table.getColumnFamily(cfName);
for (PColumn column : pfamily.getColumns()) {
ColumnRef ref = new ColumnRef(tableRef, column.getPosition());
+ if (resolveColumn) {
+ ref = context.getResolver().resolveColumn(table.getTableName().getString(), cfName, column.getName().getString());
+ }
Expression expression = ref.newColumnExpression();
projectedExpressions.add(expression);
String colName = column.getName().toString();
@@ -252,7 +274,7 @@ public class ProjectionCompiler {
}
}
- private static void projectIndexColumnFamily(StatementContext context, String cfName, TableRef tableRef, List<Expression> projectedExpressions, List<ExpressionProjector> projectedColumns) throws SQLException {
+ private static void projectIndexColumnFamily(StatementContext context, String cfName, TableRef tableRef, boolean resolveColumn, List<Expression> projectedExpressions, List<ExpressionProjector> projectedColumns) throws SQLException {
PTable index = tableRef.getTable();
PhoenixConnection conn = context.getConnection();
String tableName = index.getParentName().getString();
@@ -277,6 +299,9 @@ public class ProjectionCompiler {
throw e;
}
}
+ if (resolveColumn) {
+ ref = context.getResolver().resolveColumn(index.getTableName().getString(), indexColumn.getFamilyName() == null ? null : indexColumn.getFamilyName().getString(), indexColName);
+ }
Expression expression = ref.newColumnExpression();
projectedExpressions.add(expression);
String colName = column.getName().toString();
@@ -322,6 +347,7 @@ public class ProjectionCompiler {
ColumnResolver resolver = context.getResolver();
TableRef tableRef = context.getCurrentTable();
PTable table = tableRef.getTable();
+ boolean resolveColumn = !tableRef.equals(resolver.getTables().get(0));
boolean isWildcard = false;
Scan scan = context.getScan();
int index = 0;
@@ -336,9 +362,9 @@ public class ProjectionCompiler {
}
isWildcard = true;
if (tableRef.getTable().getType() == PTableType.INDEX && ((WildcardParseNode)node).isRewrite()) {
- projectAllIndexColumns(context, tableRef, false, projectedExpressions, projectedColumns, targetColumns);
+ projectAllIndexColumns(context, tableRef, resolveColumn, projectedExpressions, projectedColumns, targetColumns);
} else {
- projectAllTableColumns(context, tableRef, false, projectedExpressions, projectedColumns, targetColumns);
+ projectAllTableColumns(context, tableRef, resolveColumn, projectedExpressions, projectedColumns, targetColumns);
}
} else if (node instanceof TableWildcardParseNode) {
TableName tName = ((TableWildcardParseNode) node).getTableName();
@@ -362,9 +388,9 @@ public class ProjectionCompiler {
// columns are projected (which is currently true, but could change).
projectedFamilies.add(Bytes.toBytes(cfName));
if (tableRef.getTable().getType() == PTableType.INDEX && ((FamilyWildcardParseNode)node).isRewrite()) {
- projectIndexColumnFamily(context, cfName, tableRef, projectedExpressions, projectedColumns);
+ projectIndexColumnFamily(context, cfName, tableRef, resolveColumn, projectedExpressions, projectedColumns);
} else {
- projectTableColumnFamily(context, cfName, tableRef, projectedExpressions, projectedColumns);
+ projectTableColumnFamily(context, cfName, tableRef, resolveColumn, projectedExpressions, projectedColumns);
}
} else {
Expression expression = node.accept(selectVisitor);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
index 137f4e9..2276f4e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
@@ -28,9 +28,6 @@ import org.apache.hadoop.hbase.util.Pair;
import org.apache.phoenix.compile.GroupByCompiler.GroupBy;
import org.apache.phoenix.compile.JoinCompiler.JoinSpec;
import org.apache.phoenix.compile.JoinCompiler.JoinTable;
-import org.apache.phoenix.compile.JoinCompiler.JoinedTableColumnResolver;
-import org.apache.phoenix.compile.JoinCompiler.PTableWrapper;
-import org.apache.phoenix.compile.JoinCompiler.ProjectedPTableWrapper;
import org.apache.phoenix.compile.JoinCompiler.Table;
import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
import org.apache.phoenix.execute.AggregatePlan;
@@ -100,14 +97,23 @@ public class QueryCompiler {
private final List<? extends PDatum> targetColumns;
private final ParallelIteratorFactory parallelIteratorFactory;
private final SequenceManager sequenceManager;
+ private final boolean projectTuples;
private final boolean useSortMergeJoin;
private final boolean noChildParentJoinOptimization;
public QueryCompiler(PhoenixStatement statement, SelectStatement select, ColumnResolver resolver) throws SQLException {
- this(statement, select, resolver, Collections.<PDatum>emptyList(), null, new SequenceManager(statement));
+ this(statement, select, resolver, Collections.<PDatum>emptyList(), null, new SequenceManager(statement), true);
+ }
+
+ public QueryCompiler(PhoenixStatement statement, SelectStatement select, ColumnResolver resolver, boolean projectTuples) throws SQLException {
+ this(statement, select, resolver, Collections.<PDatum>emptyList(), null, new SequenceManager(statement), projectTuples);
}
public QueryCompiler(PhoenixStatement statement, SelectStatement select, ColumnResolver resolver, List<? extends PDatum> targetColumns, ParallelIteratorFactory parallelIteratorFactory, SequenceManager sequenceManager) throws SQLException {
+ this(statement, select, resolver, targetColumns, parallelIteratorFactory, sequenceManager, true);
+ }
+
+ public QueryCompiler(PhoenixStatement statement, SelectStatement select, ColumnResolver resolver, List<? extends PDatum> targetColumns, ParallelIteratorFactory parallelIteratorFactory, SequenceManager sequenceManager, boolean projectTuples) throws SQLException {
this.statement = statement;
this.select = select;
this.resolver = resolver;
@@ -115,6 +121,7 @@ public class QueryCompiler {
this.targetColumns = targetColumns;
this.parallelIteratorFactory = parallelIteratorFactory;
this.sequenceManager = sequenceManager;
+ this.projectTuples = projectTuples;
this.useSortMergeJoin = select.getHint().hasHint(Hint.USE_SORT_MERGE_JOIN);
this.noChildParentJoinOptimization = select.getHint().hasHint(Hint.NO_CHILD_PARENT_JOIN_OPTIMIZATION);
if (statement.getConnection().getQueryServices().getLowestClusterHBaseVersion() >= PhoenixDatabaseMetaData.ESSENTIAL_FAMILY_VERSION_THRESHOLD) {
@@ -194,30 +201,32 @@ public class QueryCompiler {
SelectStatement subquery = table.getAsSubquery(orderBy);
if (!table.isSubselect()) {
context.setCurrentTable(table.getTableRef());
- ProjectedPTableWrapper projectedTable = table.createProjectedTable(!projectPKColumns, context);
- TupleProjector.serializeProjectorIntoScan(context.getScan(), projectedTable.createTupleProjector());
- context.setResolver(projectedTable.createColumnResolver());
+ PTable projectedTable = table.createProjectedTable(!projectPKColumns, context);
+ TupleProjector.serializeProjectorIntoScan(context.getScan(), new TupleProjector(projectedTable));
+ context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable));
table.projectColumns(context.getScan());
return compileSingleQuery(context, subquery, binds, asSubquery, !asSubquery);
}
QueryPlan plan = compileSubquery(subquery);
- ProjectedPTableWrapper projectedTable = table.createProjectedTable(plan.getProjector());
- context.setResolver(projectedTable.createColumnResolver());
- return new TupleProjectionPlan(plan, projectedTable.createTupleProjector(), table.compilePostFilterExpression(context));
+ PTable projectedTable = table.createProjectedTable(plan.getProjector());
+ context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable));
+ return new TupleProjectionPlan(plan, new TupleProjector(plan.getProjector()), table.compilePostFilterExpression(context));
}
boolean[] starJoinVector;
if (!this.useSortMergeJoin && (starJoinVector = joinTable.getStarJoinVector()) != null) {
Table table = joinTable.getTable();
- ProjectedPTableWrapper initialProjectedTable;
+ PTable initialProjectedTable;
TableRef tableRef;
SelectStatement query;
+ TupleProjector tupleProjector;
if (!table.isSubselect()) {
context.setCurrentTable(table.getTableRef());
initialProjectedTable = table.createProjectedTable(!projectPKColumns, context);
tableRef = table.getTableRef();
table.projectColumns(context.getScan());
query = joinTable.getAsSingleSubquery(table.getAsSubquery(orderBy), asSubquery);
+ tupleProjector = new TupleProjector(initialProjectedTable);
} else {
SelectStatement subquery = table.getAsSubquery(orderBy);
QueryPlan plan = compileSubquery(subquery);
@@ -225,9 +234,10 @@ public class QueryCompiler {
tableRef = plan.getTableRef();
context.getScan().setFamilyMap(plan.getContext().getScan().getFamilyMap());
query = joinTable.getAsSingleSubquery((SelectStatement) plan.getStatement(), asSubquery);
+ tupleProjector = new TupleProjector(plan.getProjector());
}
context.setCurrentTable(tableRef);
- PTableWrapper projectedTable = initialProjectedTable;
+ PTable projectedTable = initialProjectedTable;
int count = joinSpecs.size();
ImmutableBytesPtr[] joinIds = new ImmutableBytesPtr[count];
List<Expression>[] joinExpressions = new List[count];
@@ -235,9 +245,7 @@ public class QueryCompiler {
PTable[] tables = new PTable[count];
int[] fieldPositions = new int[count];
HashSubPlan[] subPlans = new HashSubPlan[count];
- fieldPositions[0] = projectedTable.getTable().getColumns().size() - projectedTable.getTable().getPKColumns().size();
- boolean forceProjection = table.isSubselect();
- boolean needsProject = forceProjection || asSubquery;
+ fieldPositions[0] = projectedTable.getColumns().size() - projectedTable.getPKColumns().size();
for (int i = 0; i < count; i++) {
JoinSpec joinSpec = joinSpecs.get(i);
Scan subScan = ScanUtil.newScan(originalScan);
@@ -245,17 +253,12 @@ public class QueryCompiler {
QueryPlan joinPlan = compileJoinQuery(subContext, binds, joinSpec.getJoinTable(), true, true, null);
boolean hasPostReference = joinSpec.getJoinTable().hasPostReference();
if (hasPostReference) {
- PTableWrapper subProjTable = ((JoinedTableColumnResolver) subContext.getResolver()).getPTableWrapper();
- tables[i] = subProjTable.getTable();
- projectedTable = projectedTable.mergeProjectedTables(subProjTable, joinSpec.getType());
- needsProject = true;
+ tables[i] = subContext.getResolver().getTables().get(0).getTable();
+ projectedTable = JoinCompiler.joinProjectedTables(projectedTable, tables[i], joinSpec.getType());
} else {
tables[i] = null;
}
- if (!starJoinVector[i]) {
- needsProject = true;
- }
- context.setResolver((!forceProjection && starJoinVector[i]) ? joinTable.getOriginalResolver() : projectedTable.createColumnResolver());
+ context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable));
joinIds[i] = new ImmutableBytesPtr(emptyByteArray); // place-holder
Pair<List<Expression>, List<Expression>> joinConditions = joinSpec.compileJoinConditions(context, subContext, true);
joinExpressions[i] = joinConditions.getFirst();
@@ -270,17 +273,14 @@ public class QueryCompiler {
}
subPlans[i] = new HashSubPlan(i, joinPlan, optimized ? null : hashExpressions, joinSpec.isSingleValueOnly(), keyRangeLhsExpression, keyRangeRhsExpression);
}
- if (needsProject) {
- TupleProjector.serializeProjectorIntoScan(context.getScan(), initialProjectedTable.createTupleProjector());
- }
- context.setResolver(needsProject ? projectedTable.createColumnResolver() : joinTable.getOriginalResolver());
+ TupleProjector.serializeProjectorIntoScan(context.getScan(), tupleProjector);
QueryPlan plan = compileSingleQuery(context, query, binds, asSubquery, !asSubquery && joinTable.isAllLeftJoin());
Expression postJoinFilterExpression = joinTable.compilePostFilterExpression(context, table);
Integer limit = null;
if (!query.isAggregate() && !query.isDistinct() && query.getOrderBy().isEmpty()) {
limit = plan.getLimit();
}
- HashJoinInfo joinInfo = new HashJoinInfo(projectedTable.getTable(), joinIds, joinExpressions, joinTypes, starJoinVector, tables, fieldPositions, postJoinFilterExpression, limit, forceProjection);
+ HashJoinInfo joinInfo = new HashJoinInfo(projectedTable, joinIds, joinExpressions, joinTypes, starJoinVector, tables, fieldPositions, postJoinFilterExpression, limit);
return HashJoinPlan.create(joinTable.getStatement(), plan, joinInfo, subPlans);
}
@@ -296,16 +296,17 @@ public class QueryCompiler {
Scan subScan = ScanUtil.newScan(originalScan);
StatementContext lhsCtx = new StatementContext(statement, context.getResolver(), subScan, new SequenceManager(statement));
QueryPlan lhsPlan = compileJoinQuery(lhsCtx, binds, lhsJoin, true, true, null);
- PTableWrapper lhsProjTable = ((JoinedTableColumnResolver) lhsCtx.getResolver()).getPTableWrapper();
- ProjectedPTableWrapper rhsProjTable;
+ PTable rhsProjTable;
TableRef rhsTableRef;
SelectStatement rhs;
+ TupleProjector tupleProjector;
if (!rhsTable.isSubselect()) {
context.setCurrentTable(rhsTable.getTableRef());
rhsProjTable = rhsTable.createProjectedTable(!projectPKColumns, context);
rhsTableRef = rhsTable.getTableRef();
rhsTable.projectColumns(context.getScan());
rhs = rhsJoinTable.getAsSingleSubquery(rhsTable.getAsSubquery(orderBy), asSubquery);
+ tupleProjector = new TupleProjector(rhsProjTable);
} else {
SelectStatement subquery = rhsTable.getAsSubquery(orderBy);
QueryPlan plan = compileSubquery(subquery);
@@ -313,30 +314,27 @@ public class QueryCompiler {
rhsTableRef = plan.getTableRef();
context.getScan().setFamilyMap(plan.getContext().getScan().getFamilyMap());
rhs = rhsJoinTable.getAsSingleSubquery((SelectStatement) plan.getStatement(), asSubquery);
+ tupleProjector = new TupleProjector(plan.getProjector());
}
context.setCurrentTable(rhsTableRef);
- boolean forceProjection = rhsTable.isSubselect();
- context.setResolver(forceProjection ? rhsProjTable.createColumnResolver() : joinTable.getOriginalResolver());
+ context.setResolver(FromCompiler.getResolverForProjectedTable(rhsProjTable));
ImmutableBytesPtr[] joinIds = new ImmutableBytesPtr[] {new ImmutableBytesPtr(emptyByteArray)};
Pair<List<Expression>, List<Expression>> joinConditions = lastJoinSpec.compileJoinConditions(lhsCtx, context, true);
List<Expression> joinExpressions = joinConditions.getSecond();
List<Expression> hashExpressions = joinConditions.getFirst();
boolean needsMerge = lhsJoin.hasPostReference();
- boolean needsProject = forceProjection || asSubquery || needsMerge;
- PTable lhsTable = needsMerge ? lhsProjTable.getTable() : null;
- int fieldPosition = needsMerge ? rhsProjTable.getTable().getColumns().size() - rhsProjTable.getTable().getPKColumns().size() : 0;
- PTableWrapper projectedTable = needsMerge ? rhsProjTable.mergeProjectedTables(lhsProjTable, type == JoinType.Right ? JoinType.Left : type) : rhsProjTable;
- if (needsProject) {
- TupleProjector.serializeProjectorIntoScan(context.getScan(), rhsProjTable.createTupleProjector());
- }
- context.setResolver(needsProject ? projectedTable.createColumnResolver() : joinTable.getOriginalResolver());
+ PTable lhsTable = needsMerge ? lhsCtx.getResolver().getTables().get(0).getTable() : null;
+ int fieldPosition = needsMerge ? rhsProjTable.getColumns().size() - rhsProjTable.getPKColumns().size() : 0;
+ PTable projectedTable = needsMerge ? JoinCompiler.joinProjectedTables(rhsProjTable, lhsTable, type == JoinType.Right ? JoinType.Left : type) : rhsProjTable;
+ TupleProjector.serializeProjectorIntoScan(context.getScan(), tupleProjector);
+ context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable));
QueryPlan rhsPlan = compileSingleQuery(context, rhs, binds, asSubquery, !asSubquery && type == JoinType.Right);
Expression postJoinFilterExpression = joinTable.compilePostFilterExpression(context, rhsTable);
Integer limit = null;
if (!rhs.isAggregate() && !rhs.isDistinct() && rhs.getOrderBy().isEmpty()) {
limit = rhsPlan.getLimit();
}
- HashJoinInfo joinInfo = new HashJoinInfo(projectedTable.getTable(), joinIds, new List[] {joinExpressions}, new JoinType[] {type == JoinType.Right ? JoinType.Left : type}, new boolean[] {true}, new PTable[] {lhsTable}, new int[] {fieldPosition}, postJoinFilterExpression, limit, forceProjection);
+ HashJoinInfo joinInfo = new HashJoinInfo(projectedTable, joinIds, new List[] {joinExpressions}, new JoinType[] {type == JoinType.Right ? JoinType.Left : type}, new boolean[] {true}, new PTable[] {lhsTable}, new int[] {fieldPosition}, postJoinFilterExpression, limit);
Pair<Expression, Expression> keyRangeExpressions = new Pair<Expression, Expression>(null, null);
getKeyExpressionCombinations(keyRangeExpressions, context, joinTable.getStatement(), rhsTableRef, type, joinExpressions, hashExpressions);
return HashJoinPlan.create(joinTable.getStatement(), rhsPlan, joinInfo, new HashSubPlan[] {new HashSubPlan(0, lhsPlan, hashExpressions, false, keyRangeExpressions.getFirst(), keyRangeExpressions.getSecond())});
@@ -362,28 +360,27 @@ public class QueryCompiler {
StatementContext lhsCtx = new StatementContext(statement, context.getResolver(), lhsScan, new SequenceManager(statement));
boolean preserveRowkey = !projectPKColumns && type != JoinType.Full;
QueryPlan lhsPlan = compileJoinQuery(lhsCtx, binds, lhsJoin, true, !preserveRowkey, lhsOrderBy);
- PTableWrapper lhsProjTable = ((JoinedTableColumnResolver) lhsCtx.getResolver()).getPTableWrapper();
+ PTable lhsProjTable = lhsCtx.getResolver().getTables().get(0).getTable();
boolean isInRowKeyOrder = preserveRowkey && lhsPlan.getOrderBy().getOrderByExpressions().isEmpty();
Scan rhsScan = ScanUtil.newScan(originalScan);
StatementContext rhsCtx = new StatementContext(statement, context.getResolver(), rhsScan, new SequenceManager(statement));
QueryPlan rhsPlan = compileJoinQuery(rhsCtx, binds, rhsJoin, true, true, rhsOrderBy);
- PTableWrapper rhsProjTable = ((JoinedTableColumnResolver) rhsCtx.getResolver()).getPTableWrapper();
+ PTable rhsProjTable = rhsCtx.getResolver().getTables().get(0).getTable();
Pair<List<Expression>, List<Expression>> joinConditions = lastJoinSpec.compileJoinConditions(type == JoinType.Right ? rhsCtx : lhsCtx, type == JoinType.Right ? lhsCtx : rhsCtx, false);
List<Expression> lhsKeyExpressions = type == JoinType.Right ? joinConditions.getSecond() : joinConditions.getFirst();
List<Expression> rhsKeyExpressions = type == JoinType.Right ? joinConditions.getFirst() : joinConditions.getSecond();
boolean needsMerge = rhsJoin.hasPostReference();
- PTable rhsTable = needsMerge ? rhsProjTable.getTable() : null;
- int fieldPosition = needsMerge ? lhsProjTable.getTable().getColumns().size() - lhsProjTable.getTable().getPKColumns().size() : 0;
- PTableWrapper projectedTable = needsMerge ? lhsProjTable.mergeProjectedTables(rhsProjTable, type == JoinType.Right ? JoinType.Left : type) : lhsProjTable;
+ int fieldPosition = needsMerge ? lhsProjTable.getColumns().size() - lhsProjTable.getPKColumns().size() : 0;
+ PTable projectedTable = needsMerge ? JoinCompiler.joinProjectedTables(lhsProjTable, rhsProjTable, type == JoinType.Right ? JoinType.Left : type) : lhsProjTable;
- ColumnResolver resolver = projectedTable.createColumnResolver();
- TableRef tableRef = ((JoinedTableColumnResolver) resolver).getTableRef();
+ ColumnResolver resolver = FromCompiler.getResolverForProjectedTable(projectedTable);
+ TableRef tableRef = resolver.getTables().get(0);
StatementContext subCtx = new StatementContext(statement, resolver, ScanUtil.newScan(originalScan), new SequenceManager(statement));
subCtx.setCurrentTable(tableRef);
- QueryPlan innerPlan = new SortMergeJoinPlan(subCtx, joinTable.getStatement(), tableRef, type == JoinType.Right ? JoinType.Left : type, lhsPlan, rhsPlan, lhsKeyExpressions, rhsKeyExpressions, projectedTable.getTable(), lhsProjTable.getTable(), rhsTable, fieldPosition, lastJoinSpec.isSingleValueOnly());
+ QueryPlan innerPlan = new SortMergeJoinPlan(subCtx, joinTable.getStatement(), tableRef, type == JoinType.Right ? JoinType.Left : type, lhsPlan, rhsPlan, lhsKeyExpressions, rhsKeyExpressions, projectedTable, lhsProjTable, needsMerge ? rhsProjTable : null, fieldPosition, lastJoinSpec.isSingleValueOnly());
context.setCurrentTable(tableRef);
context.setResolver(resolver);
TableNode from = NODE_FACTORY.namedTable(tableRef.getTableAlias(), NODE_FACTORY.table(tableRef.getTable().getSchemaName().getString(), tableRef.getTable().getTableName().getString()));
@@ -440,7 +437,7 @@ public class QueryCompiler {
}
int maxRows = this.statement.getMaxRows();
this.statement.setMaxRows(0); // overwrite maxRows to avoid its impact on inner queries.
- QueryPlan plan = new QueryCompiler(this.statement, subquery, resolver).compile();
+ QueryPlan plan = new QueryCompiler(this.statement, subquery, resolver, false).compile();
plan = statement.getConnection().getQueryServices().getOptimizer().optimize(statement, plan);
this.statement.setMaxRows(maxRows); // restore maxRows.
return plan;
@@ -467,7 +464,14 @@ public class QueryCompiler {
}
protected QueryPlan compileSingleFlatQuery(StatementContext context, SelectStatement select, List<Object> binds, boolean asSubquery, boolean allowPageFilter, QueryPlan innerPlan, TupleProjector innerPlanTupleProjector, boolean isInRowKeyOrder) throws SQLException{
- PhoenixConnection connection = statement.getConnection();
+ PTable projectedTable = null;
+ if (this.projectTuples) {
+ projectedTable = TupleProjectionCompiler.createProjectedTable(select, context);
+ if (projectedTable != null) {
+ context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable));
+ }
+ }
+
ColumnResolver resolver = context.getResolver();
TableRef tableRef = context.getCurrentTable();
PTable table = tableRef.getTable();
@@ -485,15 +489,14 @@ public class QueryCompiler {
Expression having = HavingCompiler.compile(context, select, groupBy);
// Don't pass groupBy when building where clause expression, because we do not want to wrap these
// expressions as group by key expressions since they're pre, not post filtered.
- if (innerPlan == null) {
- context.setResolver(FromCompiler.getResolverForQuery(select, connection));
+ if (innerPlan == null && !tableRef.equals(resolver.getTables().get(0))) {
+ context.setResolver(FromCompiler.getResolverForQuery(select, this.statement.getConnection()));
}
Set<SubqueryParseNode> subqueries = Sets.<SubqueryParseNode> newHashSet();
Expression where = WhereCompiler.compile(context, select, viewWhere, subqueries);
context.setResolver(resolver); // recover resolver
OrderBy orderBy = OrderByCompiler.compile(context, select, groupBy, limit, isInRowKeyOrder);
RowProjector projector = ProjectionCompiler.compile(context, select, groupBy, asSubquery ? Collections.<PDatum>emptyList() : targetColumns);
-
// Final step is to build the query plan
if (!asSubquery) {
int maxRows = statement.getMaxRows();
@@ -506,6 +509,10 @@ public class QueryCompiler {
}
}
+ if (projectedTable != null) {
+ TupleProjector.serializeProjectorIntoScan(context.getScan(), new TupleProjector(projectedTable));
+ }
+
QueryPlan plan = innerPlan;
if (plan == null) {
ParallelIteratorFactory parallelIteratorFactory = asSubquery ? null : this.parallelIteratorFactory;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
new file mode 100644
index 0000000..72e2a26
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.compile;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.phoenix.execute.TupleProjector;
+import org.apache.phoenix.parse.AliasedNode;
+import org.apache.phoenix.parse.ColumnParseNode;
+import org.apache.phoenix.parse.FamilyWildcardParseNode;
+import org.apache.phoenix.parse.OrderByNode;
+import org.apache.phoenix.parse.ParseNode;
+import org.apache.phoenix.parse.ParseNodeFactory;
+import org.apache.phoenix.parse.SelectStatement;
+import org.apache.phoenix.parse.StatelessTraverseAllParseNodeVisitor;
+import org.apache.phoenix.parse.TableName;
+import org.apache.phoenix.parse.WildcardParseNode;
+import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
+import org.apache.phoenix.schema.ColumnNotFoundException;
+import org.apache.phoenix.schema.ColumnRef;
+import org.apache.phoenix.schema.LocalIndexDataColumnRef;
+import org.apache.phoenix.schema.PColumn;
+import org.apache.phoenix.schema.PName;
+import org.apache.phoenix.schema.PNameFactory;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTableImpl;
+import org.apache.phoenix.schema.PTableType;
+import org.apache.phoenix.schema.ProjectedColumn;
+import org.apache.phoenix.schema.TableRef;
+import org.apache.phoenix.schema.PTable.IndexType;
+import org.apache.phoenix.util.IndexUtil;
+import org.apache.phoenix.util.SchemaUtil;
+
+import com.google.common.base.Preconditions;
+
+public class TupleProjectionCompiler {
+ public static final PName PROJECTED_TABLE_SCHEMA = PNameFactory.newName(".");
+ private static final ParseNodeFactory NODE_FACTORY = new ParseNodeFactory();
+
+ public static PTable createProjectedTable(SelectStatement select, StatementContext context) throws SQLException {
+ Preconditions.checkArgument(!select.isJoin());
+ // Non-group-by or group-by aggregations will create its own projected result.
+ if (select.getInnerSelectStatement() != null
+ || select.isAggregate()
+ || select.isDistinct()
+ || (context.getResolver().getTables().get(0).getTable().getType() != PTableType.TABLE
+ && context.getResolver().getTables().get(0).getTable().getType() != PTableType.INDEX && context.getResolver().getTables().get(0).getTable().getType() != PTableType.VIEW))
+ return null;
+
+ List<PColumn> projectedColumns = new ArrayList<PColumn>();
+ boolean isWildcard = false;
+ Set<String> families = new HashSet<String>();
+ ColumnRefVisitor visitor = new ColumnRefVisitor(context);
+ TableRef tableRef = context.getCurrentTable();
+ PTable table = tableRef.getTable();
+
+ for (AliasedNode aliasedNode : select.getSelect()) {
+ ParseNode node = aliasedNode.getNode();
+ if (node instanceof WildcardParseNode) {
+ if (((WildcardParseNode) node).isRewrite()) {
+ TableRef parentTableRef = FromCompiler.getResolver(
+ NODE_FACTORY.namedTable(null, TableName.create(table.getSchemaName().getString(),
+ table.getParentTableName().getString())), context.getConnection()).resolveTable(
+ table.getSchemaName().getString(),
+ table.getParentTableName().getString());
+ for (PColumn column : parentTableRef.getTable().getColumns()) {
+ NODE_FACTORY.column(null, '"' + IndexUtil.getIndexColumnName(column) + '"', null).accept(visitor);
+ }
+ }
+ isWildcard = true;
+ } else if (node instanceof FamilyWildcardParseNode) {
+ FamilyWildcardParseNode familyWildcardNode = (FamilyWildcardParseNode) node;
+ String familyName = familyWildcardNode.getName();
+ if (familyWildcardNode.isRewrite()) {
+ TableRef parentTableRef = FromCompiler.getResolver(
+ NODE_FACTORY.namedTable(null, TableName.create(table.getSchemaName().getString(),
+ table.getParentTableName().getString())), context.getConnection()).resolveTable(
+ table.getSchemaName().getString(),
+ table.getParentTableName().getString());
+ for (PColumn column : parentTableRef.getTable().getColumnFamily(familyName).getColumns()) {
+ NODE_FACTORY.column(null, '"' + IndexUtil.getIndexColumnName(column) + '"', null).accept(visitor);
+ }
+ }
+ families.add(familyName);
+ } else {
+ node.accept(visitor);
+ }
+ }
+ if (!isWildcard) {
+ for (OrderByNode orderBy : select.getOrderBy()) {
+ orderBy.getNode().accept(visitor);
+ }
+ }
+
+ boolean hasSaltingColumn = table.getBucketNum() != null;
+ int position = hasSaltingColumn ? 1 : 0;
+ // Always project PK columns first in case there are some PK columns added by alter table.
+ for (int i = position; i < table.getPKColumns().size(); i++) {
+ PColumn sourceColumn = table.getPKColumns().get(i);
+ ColumnRef sourceColumnRef = new ColumnRef(tableRef, sourceColumn.getPosition());
+ PColumn column = new ProjectedColumn(sourceColumn.getName(), sourceColumn.getFamilyName(),
+ position++, sourceColumn.isNullable(), sourceColumnRef);
+ projectedColumns.add(column);
+ }
+ for (PColumn sourceColumn : table.getColumns()) {
+ if (SchemaUtil.isPKColumn(sourceColumn))
+ continue;
+ ColumnRef sourceColumnRef = new ColumnRef(tableRef, sourceColumn.getPosition());
+ if (!isWildcard
+ && !visitor.columnRefSet.contains(sourceColumnRef)
+ && !families.contains(sourceColumn.getFamilyName().getString()))
+ continue;
+ PColumn column = new ProjectedColumn(sourceColumn.getName(), sourceColumn.getFamilyName(),
+ position++, sourceColumn.isNullable(), sourceColumnRef);
+ projectedColumns.add(column);
+ // Wildcard or FamilyWildcard will be handled by ProjectionCompiler.
+ if (!isWildcard && !families.contains(sourceColumn.getFamilyName())) {
+ context.getScan().addColumn(sourceColumn.getFamilyName().getBytes(), sourceColumn.getName().getBytes());
+ }
+ }
+ // add LocalIndexDataColumnRef
+ for (LocalIndexDataColumnRef sourceColumnRef : visitor.localIndexColumnRefSet) {
+ PColumn column = new ProjectedColumn(sourceColumnRef.getColumn().getName(),
+ sourceColumnRef.getColumn().getFamilyName(), position++,
+ sourceColumnRef.getColumn().isNullable(), sourceColumnRef);
+ projectedColumns.add(column);
+ }
+
+ return PTableImpl.makePTable(table.getTenantId(), table.getSchemaName(), table.getName(), PTableType.PROJECTED,
+ table.getIndexState(), table.getTimeStamp(), table.getSequenceNumber(), table.getPKName(),
+ table.getBucketNum(), projectedColumns, table.getParentSchemaName(),
+ table.getParentName(), table.getIndexes(), table.isImmutableRows(), Collections.<PName>emptyList(), null, null,
+ table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(),
+ table.getIndexType());
+ }
+
+ public static PTable createProjectedTable(TableRef tableRef, List<ColumnRef> sourceColumnRefs, boolean retainPKColumns) throws SQLException {
+ PTable table = tableRef.getTable();
+ boolean hasSaltingColumn = retainPKColumns && table.getBucketNum() != null;
+ List<PColumn> projectedColumns = new ArrayList<PColumn>();
+ int position = hasSaltingColumn ? 1 : 0;
+ for (int i = position; i < sourceColumnRefs.size(); i++) {
+ ColumnRef sourceColumnRef = sourceColumnRefs.get(i);
+ PColumn sourceColumn = sourceColumnRef.getColumn();
+ String colName = sourceColumn.getName().getString();
+ String aliasedName = tableRef.getTableAlias() == null ?
+ SchemaUtil.getColumnName(table.getName().getString(), colName)
+ : SchemaUtil.getColumnName(tableRef.getTableAlias(), colName);
+
+ PColumn column = new ProjectedColumn(PNameFactory.newName(aliasedName),
+ retainPKColumns && SchemaUtil.isPKColumn(sourceColumn) ?
+ null : PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY),
+ position++, sourceColumn.isNullable(), sourceColumnRef);
+ projectedColumns.add(column);
+ }
+ return PTableImpl.makePTable(table.getTenantId(), PROJECTED_TABLE_SCHEMA, table.getName(), PTableType.PROJECTED,
+ null, table.getTimeStamp(), table.getSequenceNumber(), table.getPKName(),
+ retainPKColumns ? table.getBucketNum() : null, projectedColumns, null,
+ null, Collections.<PTable>emptyList(), table.isImmutableRows(), Collections.<PName>emptyList(), null, null,
+ table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(),
+ null);
+ }
+
+ // For extracting column references from single select statement
+ private static class ColumnRefVisitor extends StatelessTraverseAllParseNodeVisitor {
+ private final StatementContext context;
+ private final Set<ColumnRef> columnRefSet;
+ private final Set<LocalIndexDataColumnRef> localIndexColumnRefSet;
+
+ private ColumnRefVisitor(StatementContext context) {
+ this.context = context;
+ this.columnRefSet = new HashSet<ColumnRef>();
+ this.localIndexColumnRefSet = new HashSet<LocalIndexDataColumnRef>();
+ }
+
+ @Override
+ public Void visit(ColumnParseNode node) throws SQLException {
+ try {
+ columnRefSet.add(context.getResolver().resolveColumn(node.getSchemaName(), node.getTableName(), node.getName()));
+ } catch (ColumnNotFoundException e) {
+ if (context.getCurrentTable().getTable().getIndexType() == IndexType.LOCAL) {
+ try {
+ localIndexColumnRefSet.add(new LocalIndexDataColumnRef(context, node.getName()));
+ } catch (ColumnFamilyNotFoundException c) {
+ throw e;
+ }
+ } else {
+ throw e;
+ }
+ }
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
index b21cc2f..8a76564 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
@@ -419,11 +419,11 @@ public class UpsertCompiler {
// Pass scan through if same table in upsert and select so that projection is computed correctly
// Use optimizer to choose the best plan
try {
- QueryCompiler compiler = new QueryCompiler(statement, select, selectResolver, targetColumns, parallelIteratorFactoryToBe, new SequenceManager(statement));
+ QueryCompiler compiler = new QueryCompiler(statement, select, selectResolver, targetColumns, parallelIteratorFactoryToBe, new SequenceManager(statement), false);
queryPlanToBe = compiler.compile();
// This is post-fix: if the tableRef is a projected table, this means there are post-processing
// steps and parallelIteratorFactory did not take effect.
- if (queryPlanToBe.getTableRef().getTable().getType() == PTableType.JOIN || queryPlanToBe.getTableRef().getTable().getType() == PTableType.SUBQUERY) {
+ if (queryPlanToBe.getTableRef().getTable().getType() == PTableType.PROJECTED || queryPlanToBe.getTableRef().getTable().getType() == PTableType.SUBQUERY) {
parallelIteratorFactoryToBe = null;
}
} catch (MetaDataEntityNotFoundException e) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
index 406b567..9631850 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
@@ -145,7 +145,7 @@ public class WhereCompiler {
expression = AndExpression.create(filters);
}
- if (context.getCurrentTable().getTable().getType() != PTableType.JOIN && context.getCurrentTable().getTable().getType() != PTableType.SUBQUERY) {
+ if (context.getCurrentTable().getTable().getType() != PTableType.PROJECTED && context.getCurrentTable().getTable().getType() != PTableType.SUBQUERY) {
expression = WhereOptimizer.pushKeyExpressionsToScan(context, statement, expression, extractedNodes);
}
setScanFilter(context, statement, expression, whereCompiler.disambiguateWithFamily, hashJoinOptimization);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
index 69cdcb6..25ac408 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
@@ -29,6 +29,7 @@ import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.KeyValue.Type;
+import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
@@ -47,6 +48,8 @@ import org.apache.phoenix.schema.KeyValueSchema;
import org.apache.phoenix.schema.StaleRegionBoundaryCacheException;
import org.apache.phoenix.schema.ValueBitSet;
import org.apache.phoenix.schema.tuple.MultiKeyValueTuple;
+import org.apache.phoenix.schema.tuple.ResultTuple;
+import org.apache.phoenix.schema.tuple.Tuple;
import org.apache.phoenix.util.IndexUtil;
import org.apache.phoenix.util.ScanUtil;
import org.apache.phoenix.util.ServerUtil;
@@ -216,9 +219,10 @@ abstract public class BaseScannerRegionObserver extends BaseRegionObserver {
final RegionScanner s, final int offset, final Scan scan,
final ColumnReference[] dataColumns, final TupleProjector tupleProjector,
final HRegion dataRegion, final IndexMaintainer indexMaintainer,
- final byte[][] viewConstants, final ImmutableBytesWritable ptr) {
+ final byte[][] viewConstants, final TupleProjector projector,
+ final ImmutableBytesWritable ptr) {
return getWrappedScanner(c, s, null, null, offset, scan, dataColumns, tupleProjector,
- dataRegion, indexMaintainer, viewConstants, null, null, ptr);
+ dataRegion, indexMaintainer, viewConstants, null, null, projector, ptr);
}
/**
@@ -241,7 +245,8 @@ abstract public class BaseScannerRegionObserver extends BaseRegionObserver {
final ColumnReference[] dataColumns, final TupleProjector tupleProjector,
final HRegion dataRegion, final IndexMaintainer indexMaintainer,
final byte[][] viewConstants, final KeyValueSchema kvSchema,
- final ValueBitSet kvSchemaBitSet, final ImmutableBytesWritable ptr) {
+ final ValueBitSet kvSchemaBitSet, final TupleProjector projector,
+ final ImmutableBytesWritable ptr) {
return new RegionScanner() {
@Override
@@ -303,6 +308,11 @@ abstract public class BaseScannerRegionObserver extends BaseRegionObserver {
IndexUtil.wrapResultUsingOffset(c, result, offset, dataColumns,
tupleProjector, dataRegion, indexMaintainer, viewConstants, ptr);
}
+ if (projector != null) {
+ Tuple tuple = projector.projectResults(new ResultTuple(Result.create(result)));
+ result.clear();
+ result.add(tuple.getValue(0));
+ }
// There is a scanattribute set to retrieve the specific array element
return next;
} catch (Throwable t) {
@@ -325,6 +335,11 @@ abstract public class BaseScannerRegionObserver extends BaseRegionObserver {
IndexUtil.wrapResultUsingOffset(c, result, offset, dataColumns,
tupleProjector, dataRegion, indexMaintainer, viewConstants, ptr);
}
+ if (projector != null) {
+ Tuple tuple = projector.projectResults(new ResultTuple(Result.create(result)));
+ result.clear();
+ result.add(tuple.getValue(0));
+ }
// There is a scanattribute set to retrieve the specific array element
return next;
} catch (Throwable t) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GroupedAggregateRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GroupedAggregateRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GroupedAggregateRegionObserver.java
index 0984b06..1f1ba36 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GroupedAggregateRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GroupedAggregateRegionObserver.java
@@ -131,7 +131,10 @@ public class GroupedAggregateRegionObserver extends BaseScannerRegionObserver {
HRegion dataRegion = null;
byte[][] viewConstants = null;
ColumnReference[] dataColumns = IndexUtil.deserializeDataTableColumnsToJoin(scan);
- if (ScanUtil.isLocalIndex(scan)) {
+
+ final TupleProjector p = TupleProjector.deserializeProjectorFromScan(scan);
+ final HashJoinInfo j = HashJoinInfo.deserializeHashJoinFromScan(scan);
+ if (ScanUtil.isLocalIndex(scan) || (j == null && p != null)) {
if (dataColumns != null) {
tupleProjector = IndexUtil.getTupleProjector(scan, dataColumns);
dataRegion = IndexUtil.getDataRegion(c.getEnvironment());
@@ -140,12 +143,10 @@ public class GroupedAggregateRegionObserver extends BaseScannerRegionObserver {
ImmutableBytesWritable tempPtr = new ImmutableBytesWritable();
innerScanner =
getWrappedScanner(c, innerScanner, offset, scan, dataColumns, tupleProjector,
- dataRegion, indexMaintainers == null ? null : indexMaintainers.get(0), viewConstants, tempPtr);
+ dataRegion, indexMaintainers == null ? null : indexMaintainers.get(0), viewConstants, p, tempPtr);
}
- final TupleProjector p = TupleProjector.deserializeProjectorFromScan(scan);
- final HashJoinInfo j = HashJoinInfo.deserializeHashJoinFromScan(scan);
- if (p != null || j != null) {
+ if (j != null) {
innerScanner =
new HashJoinRegionScanner(innerScanner, p, j, ScanUtil.getTenantId(scan),
c.getEnvironment());
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java
index 176520e..cdfc771 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java
@@ -70,39 +70,37 @@ public class HashJoinRegionScanner implements RegionScanner {
this.hasMore = true;
this.count = 0;
this.limit = Long.MAX_VALUE;
- if (joinInfo != null) {
- for (JoinType type : joinInfo.getJoinTypes()) {
- if (type != JoinType.Inner && type != JoinType.Left && type != JoinType.Semi && type != JoinType.Anti)
- throw new DoNotRetryIOException("Got join type '" + type + "'. Expect only INNER or LEFT with hash-joins.");
- }
- if (joinInfo.getLimit() != null) {
- this.limit = joinInfo.getLimit();
- }
- int count = joinInfo.getJoinIds().length;
- this.tempTuples = new List[count];
- this.hashCaches = new HashCache[count];
- this.tempSrcBitSet = new ValueBitSet[count];
- TenantCache cache = GlobalCache.getTenantCache(env, tenantId);
- for (int i = 0; i < count; i++) {
- ImmutableBytesPtr joinId = joinInfo.getJoinIds()[i];
- if (joinId.getLength() == 0) { // semi-join optimized into skip-scan
- hashCaches[i] = null;
- tempSrcBitSet[i] = null;
- tempTuples[i] = null;
- continue;
- }
- HashCache hashCache = (HashCache)cache.getServerCache(joinId);
- if (hashCache == null)
- throw new DoNotRetryIOException("Could not find hash cache for joinId: "
- + Bytes.toString(joinId.get(), joinId.getOffset(), joinId.getLength())
- + ". The cache might have expired and have been removed.");
- hashCaches[i] = hashCache;
- tempSrcBitSet[i] = ValueBitSet.newInstance(joinInfo.getSchemas()[i]);
- }
- if (this.projector != null) {
- this.tempDestBitSet = ValueBitSet.newInstance(joinInfo.getJoinedSchema());
- this.projector.setValueBitSet(tempDestBitSet);
+ for (JoinType type : joinInfo.getJoinTypes()) {
+ if (type != JoinType.Inner && type != JoinType.Left && type != JoinType.Semi && type != JoinType.Anti)
+ throw new DoNotRetryIOException("Got join type '" + type + "'. Expect only INNER or LEFT with hash-joins.");
+ }
+ if (joinInfo.getLimit() != null) {
+ this.limit = joinInfo.getLimit();
+ }
+ int count = joinInfo.getJoinIds().length;
+ this.tempTuples = new List[count];
+ this.hashCaches = new HashCache[count];
+ this.tempSrcBitSet = new ValueBitSet[count];
+ TenantCache cache = GlobalCache.getTenantCache(env, tenantId);
+ for (int i = 0; i < count; i++) {
+ ImmutableBytesPtr joinId = joinInfo.getJoinIds()[i];
+ if (joinId.getLength() == 0) { // semi-join optimized into skip-scan
+ hashCaches[i] = null;
+ tempSrcBitSet[i] = null;
+ tempTuples[i] = null;
+ continue;
}
+ HashCache hashCache = (HashCache)cache.getServerCache(joinId);
+ if (hashCache == null)
+ throw new DoNotRetryIOException("Could not find hash cache for joinId: "
+ + Bytes.toString(joinId.get(), joinId.getOffset(), joinId.getLength())
+ + ". The cache might have expired and have been removed.");
+ hashCaches[i] = hashCache;
+ tempSrcBitSet[i] = ValueBitSet.newInstance(joinInfo.getSchemas()[i]);
+ }
+ if (this.projector != null) {
+ this.tempDestBitSet = ValueBitSet.newInstance(joinInfo.getJoinedSchema());
+ this.projector.setValueBitSet(tempDestBitSet);
}
}
@@ -111,13 +109,11 @@ public class HashJoinRegionScanner implements RegionScanner {
return;
Tuple tuple = new ResultTuple(Result.create(result));
- if (joinInfo == null || joinInfo.forceProjection()) {
+ // For backward compatibility. In new versions, HashJoinInfo.forceProjection()
+ // always returns true.
+ if (joinInfo.forceProjection()) {
tuple = projector.projectResults(tuple);
}
- if (joinInfo == null) {
- resultQueue.offer(tuple);
- return;
- }
if (hasBatchLimit)
throw new UnsupportedOperationException("Cannot support join operations in scans with limit");
@@ -147,7 +143,7 @@ public class HashJoinRegionScanner implements RegionScanner {
}
} else {
KeyValueSchema schema = joinInfo.getJoinedSchema();
- if (!joinInfo.forceProjection()) {
+ if (!joinInfo.forceProjection()) { // backward compatibility
tuple = projector.projectResults(tuple);
}
resultQueue.offer(tuple);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java
index 9270495..ddde407 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java
@@ -199,15 +199,16 @@ public class ScanRegionObserver extends BaseScannerRegionObserver {
indexMaintainer = indexMaintainers.get(0);
viewConstants = IndexUtil.deserializeViewConstantsFromScan(scan);
}
+
+ final TupleProjector p = TupleProjector.deserializeProjectorFromScan(scan);
+ final HashJoinInfo j = HashJoinInfo.deserializeHashJoinFromScan(scan);
innerScanner =
getWrappedScanner(c, innerScanner, arrayKVRefs, arrayFuncRefs, offset, scan,
dataColumns, tupleProjector, dataRegion, indexMaintainer, viewConstants,
- kvSchema, kvSchemaBitSet, ptr);
+ kvSchema, kvSchemaBitSet, j == null ? p : null, ptr);
- final TupleProjector p = TupleProjector.deserializeProjectorFromScan(scan);
- final HashJoinInfo j = HashJoinInfo.deserializeHashJoinFromScan(scan);
final ImmutableBytesWritable tenantId = ScanUtil.getTenantId(scan);
- if (p != null || j != null) {
+ if (j != null) {
innerScanner = new HashJoinRegionScanner(innerScanner, p, j, tenantId, c.getEnvironment());
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
index 71c4dc6..72a0a64 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
@@ -214,7 +214,9 @@ public class UngroupedAggregateRegionObserver extends BaseScannerRegionObserver{
byte[][] viewConstants = null;
ColumnReference[] dataColumns = IndexUtil.deserializeDataTableColumnsToJoin(scan);
boolean localIndexScan = ScanUtil.isLocalIndex(scan);
- if (localIndexScan && !isDelete) {
+ final TupleProjector p = TupleProjector.deserializeProjectorFromScan(scan);
+ final HashJoinInfo j = HashJoinInfo.deserializeHashJoinFromScan(scan);
+ if ((localIndexScan && !isDelete) || (j == null && p != null)) {
if (dataColumns != null) {
tupleProjector = IndexUtil.getTupleProjector(scan, dataColumns);
dataRegion = IndexUtil.getDataRegion(c.getEnvironment());
@@ -223,12 +225,10 @@ public class UngroupedAggregateRegionObserver extends BaseScannerRegionObserver{
ImmutableBytesWritable tempPtr = new ImmutableBytesWritable();
theScanner =
getWrappedScanner(c, theScanner, offset, scan, dataColumns, tupleProjector,
- dataRegion, indexMaintainers == null ? null : indexMaintainers.get(0), viewConstants, tempPtr);
+ dataRegion, indexMaintainers == null ? null : indexMaintainers.get(0), viewConstants, p, tempPtr);
}
- final TupleProjector p = TupleProjector.deserializeProjectorFromScan(scan);
- final HashJoinInfo j = HashJoinInfo.deserializeHashJoinFromScan(scan);
- if (p != null || j != null) {
+ if (j != null) {
theScanner = new HashJoinRegionScanner(theScanner, p, j, ScanUtil.getTenantId(scan), c.getEnvironment());
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjector.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjector.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjector.java
index 77682e4..a4728e9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjector.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjector.java
@@ -32,19 +32,23 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.WritableUtils;
import org.apache.phoenix.compile.ColumnProjector;
-import org.apache.phoenix.compile.JoinCompiler.ProjectedPTableWrapper;
import org.apache.phoenix.compile.RowProjector;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.ExpressionType;
import org.apache.phoenix.schema.KeyValueSchema;
import org.apache.phoenix.schema.KeyValueSchema.KeyValueSchemaBuilder;
import org.apache.phoenix.schema.PColumn;
+import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTableType;
+import org.apache.phoenix.schema.ProjectedColumn;
import org.apache.phoenix.schema.ValueBitSet;
import org.apache.phoenix.schema.tuple.BaseTuple;
import org.apache.phoenix.schema.tuple.Tuple;
import org.apache.phoenix.util.KeyValueUtil;
import org.apache.phoenix.util.SchemaUtil;
+import com.google.common.base.Preconditions;
+
public class TupleProjector {
public static final byte[] VALUE_COLUMN_FAMILY = Bytes.toBytes("_v");
public static final byte[] VALUE_COLUMN_QUALIFIER = new byte[0];
@@ -70,16 +74,16 @@ public class TupleProjector {
valueSet = ValueBitSet.newInstance(schema);
}
- public TupleProjector(ProjectedPTableWrapper projected) {
- List<PColumn> columns = projected.getTable().getColumns();
- expressions = new Expression[columns.size() - projected.getTable().getPKColumns().size()];
- // we do not count minNullableIndex for we might do later merge.
+ public TupleProjector(PTable projectedTable) {
+ Preconditions.checkArgument(projectedTable.getType() == PTableType.PROJECTED);
+ List<PColumn> columns = projectedTable.getColumns();
+ this.expressions = new Expression[columns.size() - projectedTable.getPKColumns().size()];
KeyValueSchemaBuilder builder = new KeyValueSchemaBuilder(0);
int i = 0;
- for (PColumn column : projected.getTable().getColumns()) {
+ for (PColumn column : columns) {
if (!SchemaUtil.isPKColumn(column)) {
builder.addField(column);
- expressions[i++] = projected.getSourceExpression(column);
+ expressions[i++] = ((ProjectedColumn) column).getSourceColumnRef().newColumnExpression();
}
}
schema = builder.build();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/join/HashJoinInfo.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/join/HashJoinInfo.java b/phoenix-core/src/main/java/org/apache/phoenix/join/HashJoinInfo.java
index ad96061..ea78671 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/join/HashJoinInfo.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/join/HashJoinInfo.java
@@ -50,10 +50,9 @@ public class HashJoinInfo {
private int[] fieldPositions;
private Expression postJoinFilterExpression;
private Integer limit;
- private boolean forceProjection;
- public HashJoinInfo(PTable joinedTable, ImmutableBytesPtr[] joinIds, List<Expression>[] joinExpressions, JoinType[] joinTypes, boolean[] earlyEvaluation, PTable[] tables, int[] fieldPositions, Expression postJoinFilterExpression, Integer limit, boolean forceProjection) {
- this(buildSchema(joinedTable), joinIds, joinExpressions, joinTypes, earlyEvaluation, buildSchemas(tables), fieldPositions, postJoinFilterExpression, limit, forceProjection);
+ public HashJoinInfo(PTable joinedTable, ImmutableBytesPtr[] joinIds, List<Expression>[] joinExpressions, JoinType[] joinTypes, boolean[] earlyEvaluation, PTable[] tables, int[] fieldPositions, Expression postJoinFilterExpression, Integer limit) {
+ this(buildSchema(joinedTable), joinIds, joinExpressions, joinTypes, earlyEvaluation, buildSchemas(tables), fieldPositions, postJoinFilterExpression, limit);
}
private static KeyValueSchema[] buildSchemas(PTable[] tables) {
@@ -76,7 +75,7 @@ public class HashJoinInfo {
return builder.build();
}
- private HashJoinInfo(KeyValueSchema joinedSchema, ImmutableBytesPtr[] joinIds, List<Expression>[] joinExpressions, JoinType[] joinTypes, boolean[] earlyEvaluation, KeyValueSchema[] schemas, int[] fieldPositions, Expression postJoinFilterExpression, Integer limit, boolean forceProjection) {
+ private HashJoinInfo(KeyValueSchema joinedSchema, ImmutableBytesPtr[] joinIds, List<Expression>[] joinExpressions, JoinType[] joinTypes, boolean[] earlyEvaluation, KeyValueSchema[] schemas, int[] fieldPositions, Expression postJoinFilterExpression, Integer limit) {
this.joinedSchema = joinedSchema;
this.joinIds = joinIds;
this.joinExpressions = joinExpressions;
@@ -86,7 +85,6 @@ public class HashJoinInfo {
this.fieldPositions = fieldPositions;
this.postJoinFilterExpression = postJoinFilterExpression;
this.limit = limit;
- this.forceProjection = forceProjection;
}
public KeyValueSchema getJoinedSchema() {
@@ -124,15 +122,11 @@ public class HashJoinInfo {
public Integer getLimit() {
return limit;
}
-
- /*
- * If the LHS table is a sub-select, we always do projection, since
- * the ON expressions reference only projected columns.
- */
+
public boolean forceProjection() {
- return forceProjection;
+ return true;
}
-
+
public static void serializeHashJoinIntoScan(Scan scan, HashJoinInfo joinInfo) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
@@ -159,7 +153,7 @@ public class HashJoinInfo {
WritableUtils.writeVInt(output, -1);
}
WritableUtils.writeVInt(output, joinInfo.limit == null ? -1 : joinInfo.limit);
- output.writeBoolean(joinInfo.forceProjection);
+ output.writeBoolean(true);
scan.setAttribute(HASH_JOIN, stream.toByteArray());
} catch (IOException e) {
throw new RuntimeException(e);
@@ -216,17 +210,16 @@ public class HashJoinInfo {
postJoinFilterExpression.readFields(input);
}
int limit = -1;
- boolean forceProjection = false;
// Read these and ignore if we don't find them as they were not
// present in Apache Phoenix 3.0.0 release. This allows a newer
// 3.1 server to work with an older 3.0 client without force
// both to be upgraded in lock step.
try {
limit = WritableUtils.readVInt(input);
- forceProjection = input.readBoolean();
+ input.readBoolean(); // discarded info in new versions
} catch (EOFException ignore) {
}
- return new HashJoinInfo(joinedSchema, joinIds, joinExpressions, joinTypes, earlyEvaluation, schemas, fieldPositions, postJoinFilterExpression, limit >= 0 ? limit : null, forceProjection);
+ return new HashJoinInfo(joinedSchema, joinIds, joinExpressions, joinTypes, earlyEvaluation, schemas, fieldPositions, postJoinFilterExpression, limit >= 0 ? limit : null);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java
----------------------------------------------------------------------
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 a51723b..382bba5 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
@@ -113,14 +113,13 @@ public class QueryOptimizer {
SelectStatement select = (SelectStatement)dataPlan.getStatement();
// Exit early if we have a point lookup as we can't get better than that
if (!useIndexes
- || select.isJoin()
- || dataPlan.getContext().getResolver().getTables().size() > 1
- || select.getInnerSelectStatement() != null
|| (dataPlan.getContext().getScanRanges().isPointLookup() && stopAtBestPlan)) {
return Collections.singletonList(dataPlan);
}
- PTable dataTable = dataPlan.getTableRef().getTable();
- List<PTable>indexes = Lists.newArrayList(dataTable.getIndexes());
+ // For single query tuple projection, indexes are inherited from the original table to the projected
+ // table; otherwise not. So we pass projected table here, which is enough to tell if this is from a
+ // single query or a part of join query.
+ List<PTable>indexes = Lists.newArrayList(dataPlan.getContext().getResolver().getTables().get(0).getTable().getIndexes());
if (indexes.isEmpty() || dataPlan.isDegenerate() || dataPlan.getTableRef().hasDynamicCols() || select.getHint().hasHint(Hint.NO_INDEX)) {
return Collections.singletonList(dataPlan);
}
@@ -138,7 +137,7 @@ public class QueryOptimizer {
targetColumns = targetDatums;
}
- SelectStatement translatedIndexSelect = IndexStatementRewriter.translate(select, dataPlan.getContext().getResolver());
+ SelectStatement translatedIndexSelect = IndexStatementRewriter.translate(select, FromCompiler.getResolver(dataPlan.getTableRef()));
List<QueryPlan> plans = Lists.newArrayListWithExpectedSize(1 + indexes.size());
plans.add(dataPlan);
QueryPlan hintedPlan = getHintedQueryPlan(statement, translatedIndexSelect, indexes, targetColumns, parallelIteratorFactory, plans);
@@ -230,12 +229,14 @@ public class QueryOptimizer {
TableNode table = FACTORY.namedTable(alias, FACTORY.table(schemaName, tableName));
SelectStatement indexSelect = FACTORY.select(select, table);
ColumnResolver resolver = FromCompiler.getResolverForQuery(indexSelect, statement.getConnection());
+ // We will or will not do tuple projection according to the data plan.
+ boolean isProjected = dataPlan.getContext().getResolver().getTables().get(0).getTable().getType() == PTableType.PROJECTED;
// Check index state of now potentially updated index table to make sure it's active
if (PIndexState.ACTIVE.equals(resolver.getTables().get(0).getTable().getIndexState())) {
try {
// translate nodes that match expressions that are indexed to the associated column parse node
indexSelect = ParseNodeRewriter.rewrite(indexSelect, new IndexExpressionParseNodeRewriter(index, statement.getConnection()));
- QueryCompiler compiler = new QueryCompiler(statement, indexSelect, resolver, targetColumns, parallelIteratorFactory, dataPlan.getContext().getSequenceManager());
+ QueryCompiler compiler = new QueryCompiler(statement, indexSelect, resolver, targetColumns, parallelIteratorFactory, dataPlan.getContext().getSequenceManager(), isProjected);
QueryPlan plan = compiler.compile();
// If query doesn't have where clause and some of columns to project are missing
@@ -267,7 +268,7 @@ public class QueryOptimizer {
ParseNode where = dataSelect.getWhere();
if (isHinted && where != null) {
StatementContext context = new StatementContext(statement, resolver);
- WhereConditionRewriter whereRewriter = new WhereConditionRewriter(dataPlan.getContext().getResolver(), context);
+ WhereConditionRewriter whereRewriter = new WhereConditionRewriter(FromCompiler.getResolver(dataPlan.getTableRef()), context);
where = where.accept(whereRewriter);
if (where != null) {
PTable dataTable = dataPlan.getTableRef().getTable();
@@ -301,7 +302,7 @@ public class QueryOptimizer {
query = SubqueryRewriter.transform(query, queryResolver, statement.getConnection());
queryResolver = FromCompiler.getResolverForQuery(query, statement.getConnection());
query = StatementNormalizer.normalize(query, queryResolver);
- QueryPlan plan = new QueryCompiler(statement, query, queryResolver).compile();
+ QueryPlan plan = new QueryCompiler(statement, query, queryResolver, targetColumns, parallelIteratorFactory, dataPlan.getContext().getSequenceManager(), isProjected).compile();
return plan;
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java
index c6dd1f4..76f6218 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/ColumnRef.java
@@ -105,7 +105,7 @@ public class ColumnRef {
displayName);
}
- if (table.getType() == PTableType.JOIN || table.getType() == PTableType.SUBQUERY) {
+ if (table.getType() == PTableType.PROJECTED || table.getType() == PTableType.SUBQUERY) {
return new ProjectedColumnExpression(column, table, displayName);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/schema/LocalIndexDataColumnRef.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/LocalIndexDataColumnRef.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/LocalIndexDataColumnRef.java
index 62ef431..270c66d 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/LocalIndexDataColumnRef.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/LocalIndexDataColumnRef.java
@@ -20,16 +20,13 @@ package org.apache.phoenix.schema;
import java.sql.SQLException;
import java.util.Set;
-import org.apache.hadoop.hbase.util.Bytes;
import org.apache.phoenix.compile.FromCompiler;
import org.apache.phoenix.compile.StatementContext;
import org.apache.phoenix.expression.ColumnExpression;
import org.apache.phoenix.expression.ProjectedColumnExpression;
import org.apache.phoenix.parse.ParseNodeFactory;
import org.apache.phoenix.parse.TableName;
-import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.util.IndexUtil;
-import org.apache.phoenix.util.SchemaUtil;
public class LocalIndexDataColumnRef extends ColumnRef {
final private int position;
@@ -62,11 +59,7 @@ public class LocalIndexDataColumnRef extends ColumnRef {
@Override
public ColumnExpression newColumnExpression(boolean schemaNameCaseSensitive, boolean colNameCaseSensitive) {
- PTable table = this.getTable();
- PColumn column = this.getColumn();
- // TODO: util for this or store in member variable
- byte[] defaultFamily = table.getDefaultFamilyName() == null ? QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES : table.getDefaultFamilyName().getBytes();
- String displayName = SchemaUtil.getColumnDisplayName(Bytes.compareTo(defaultFamily, column.getFamilyName().getBytes()) == 0 ? null : column.getFamilyName().getBytes(), column.getName().getBytes());
+ String displayName = this.getTableRef().getColumnDisplayName(this, schemaNameCaseSensitive, colNameCaseSensitive);
return new ProjectedColumnExpression(this.getColumn(), columns, position, displayName);
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index 831616b..e133433 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -764,7 +764,7 @@ public class MetaDataClient {
String tableName = getFullTableName(dataTableRef);
String query = "SELECT count(*) FROM " + tableName;
final QueryPlan plan = statement.compileQuery(query);
- TableRef tableRef = plan.getContext().getResolver().getTables().get(0);
+ TableRef tableRef = plan.getTableRef();
// Set attribute on scan that UngroupedAggregateRegionObserver will switch on.
// We'll detect that this attribute was set the server-side and write the index
// rows per region as a result. The value of the attribute will be our persisted
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableType.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableType.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableType.java
index 23ba829..019c0e1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableType.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableType.java
@@ -27,7 +27,7 @@ public enum PTableType {
TABLE("u", "TABLE"),
VIEW("v", "VIEW"),
INDEX("i", "INDEX"),
- JOIN("j", "JOIN"),
+ PROJECTED("p", "PROJECTED"),
SUBQUERY("q", "SUBQUERY");
private final PName value;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/schema/ProjectedColumn.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/ProjectedColumn.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/ProjectedColumn.java
new file mode 100644
index 0000000..19dd1c1
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/ProjectedColumn.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.schema;
+
+public class ProjectedColumn extends DelegateColumn {
+
+ private final PName name;
+ private final PName familyName;
+ private final int position;
+ private final boolean nullable;
+ private final ColumnRef sourceColumnRef;
+
+ public ProjectedColumn(PName name, PName familyName, int position, boolean nullable, ColumnRef sourceColumnRef) {
+ super(sourceColumnRef.getColumn());
+ this.name = name;
+ this.familyName = familyName;
+ this.position = position;
+ this.nullable = nullable;
+ this.sourceColumnRef = sourceColumnRef;
+ }
+
+ @Override
+ public PName getName() {
+ return name;
+ }
+
+ public PName getFamilyName() {
+ return familyName;
+ }
+
+ @Override
+ public int getPosition() {
+ return position;
+ }
+
+ @Override
+ public boolean isNullable() {
+ return nullable;
+ }
+
+ public ColumnRef getSourceColumnRef() {
+ return sourceColumnRef;
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/main/java/org/apache/phoenix/schema/TableRef.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/TableRef.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/TableRef.java
index b64912b..bd88770 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/TableRef.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/TableRef.java
@@ -18,6 +18,7 @@
package org.apache.phoenix.schema;
import org.apache.hadoop.hbase.HConstants;
+import org.apache.phoenix.compile.TupleProjectionCompiler;
import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.util.IndexUtil;
import org.apache.phoenix.util.SchemaUtil;
@@ -73,9 +74,10 @@ public class TableRef {
String cq = null;
PColumn column = ref.getColumn();
String name = column.getName().getString();
- boolean isIndex = table.getType() == PTableType.INDEX;
- if (table.getType() == PTableType.JOIN || table.getType() == PTableType.SUBQUERY) {
- cq = column.getName().getString();
+ boolean isIndex = IndexUtil.isIndexColumn(name);
+ if ((table.getType() == PTableType.PROJECTED && TupleProjectionCompiler.PROJECTED_TABLE_SCHEMA.equals(table.getSchemaName()))
+ || table.getType() == PTableType.SUBQUERY) {
+ cq = name;
}
else if (SchemaUtil.isPKColumn(column)) {
cq = isIndex ? IndexUtil.getDataColumnName(name) : name;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/3f829751/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
index 01f28ae..3a012fb 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereCompilerTest.java
@@ -619,7 +619,7 @@ public class WhereCompilerTest extends BaseConnectionlessQueryTest {
pointRange(tenantId1),
pointRange(tenantId2),
pointRange(tenantId3))),
- plan.getContext().getResolver().getTables().get(0).getTable().getRowKeySchema()),
+ plan.getTableRef().getTable().getRowKeySchema()),
filter);
}
@@ -642,7 +642,7 @@ public class WhereCompilerTest extends BaseConnectionlessQueryTest {
pointRange(tenantId1),
pointRange(tenantId2),
pointRange(tenantId3))),
- plan.getContext().getResolver().getTables().get(0).getTable().getRowKeySchema()),
+ plan.getTableRef().getTable().getRowKeySchema()),
filter);
byte[] startRow = PVarchar.INSTANCE.toBytes(tenantId1);
@@ -705,7 +705,7 @@ public class WhereCompilerTest extends BaseConnectionlessQueryTest {
true,
Bytes.toBytes(entityId2),
true))),
- plan.getContext().getResolver().getTables().get(0).getTable().getRowKeySchema()),
+ plan.getTableRef().getTable().getRowKeySchema()),
filter);
}