use of org.apache.phoenix.schema.LocalIndexDataColumnRef in project phoenix by apache.
the class TupleProjectionCompiler method createProjectedTable.
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.getFrom() == 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);
}
} else {
for (PColumn column : table.getColumnFamily(familyName).getColumns()) {
NODE_FACTORY.column(TableName.create(null, familyName), '"' + column.getName().getString() + '"', 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, null);
projectedColumns.add(column);
}
List<ColumnRef> nonPkColumnRefList = new ArrayList<ColumnRef>(visitor.nonPkColumnRefSet);
for (PColumn sourceColumn : table.getColumns()) {
if (SchemaUtil.isPKColumn(sourceColumn))
continue;
ColumnRef sourceColumnRef = new ColumnRef(tableRef, sourceColumn.getPosition());
if (!isWildcard && !visitor.nonPkColumnRefSet.contains(sourceColumnRef) && !families.contains(sourceColumn.getFamilyName().getString()))
continue;
PColumn column = new ProjectedColumn(sourceColumn.getName(), sourceColumn.getFamilyName(), visitor.nonPkColumnRefSet.contains(sourceColumnRef) ? position + nonPkColumnRefList.indexOf(sourceColumnRef) : position++, sourceColumn.isNullable(), sourceColumnRef, sourceColumn.getColumnQualifierBytes());
projectedColumns.add(column);
// Wildcard or FamilyWildcard will be handled by ProjectionCompiler.
if (!isWildcard && !families.contains(sourceColumn.getFamilyName())) {
EncodedColumnsUtil.setColumns(column, table, context.getScan());
}
}
// add LocalIndexDataColumnRef
position = projectedColumns.size();
for (LocalIndexDataColumnRef sourceColumnRef : visitor.localIndexColumnRefSet) {
PColumn column = new ProjectedColumn(sourceColumnRef.getColumn().getName(), sourceColumnRef.getColumn().getFamilyName(), position++, sourceColumnRef.getColumn().isNullable(), sourceColumnRef, sourceColumnRef.getColumn().getColumnQualifierBytes());
projectedColumns.add(column);
}
return PTableImpl.makePTable(table.getTenantId(), table.getSchemaName(), table.getTableName(), PTableType.PROJECTED, table.getIndexState(), table.getTimeStamp(), table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), projectedColumns, table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(), table.isImmutableRows(), Collections.<PName>emptyList(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName(), table.isAppendOnlySchema(), table.getImmutableStorageScheme(), table.getEncodingScheme(), table.getEncodedCQCounter(), table.useStatsForParallelization());
}
use of org.apache.phoenix.schema.LocalIndexDataColumnRef in project phoenix by apache.
the class ProjectionCompiler method projectIndexColumnFamily.
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();
PTable table = conn.getTable(new PTableKey(conn.getTenantId(), tableName));
PColumnFamily pfamily = table.getColumnFamily(cfName);
for (PColumn column : pfamily.getColumns()) {
String indexColName = IndexUtil.getIndexColumnName(column);
PColumn indexColumn = null;
ColumnRef ref = null;
String indexColumnFamily = null;
try {
indexColumn = index.getColumnForColumnName(indexColName);
ref = new ColumnRef(tableRef, indexColumn.getPosition());
indexColumnFamily = indexColumn.getFamilyName() == null ? null : indexColumn.getFamilyName().getString();
} catch (ColumnNotFoundException e) {
if (index.getIndexType() == IndexType.LOCAL) {
try {
ref = new LocalIndexDataColumnRef(context, indexColName);
indexColumn = ref.getColumn();
indexColumnFamily = indexColumn.getFamilyName() == null ? null : (index.getIndexType() == IndexType.LOCAL ? IndexUtil.getLocalIndexColumnFamily(indexColumn.getFamilyName().getString()) : indexColumn.getFamilyName().getString());
} catch (ColumnFamilyNotFoundException c) {
throw e;
}
} else {
throw e;
}
}
if (resolveColumn) {
ref = context.getResolver().resolveColumn(index.getTableName().getString(), indexColumnFamily, indexColName);
}
Expression expression = ref.newColumnExpression();
projectedExpressions.add(expression);
String colName = column.getName().toString();
boolean isCaseSensitive = !SchemaUtil.normalizeIdentifier(colName).equals(colName);
projectedColumns.add(new ExpressionProjector(colName, tableRef.getTableAlias() == null ? table.getName().getString() : tableRef.getTableAlias(), expression, isCaseSensitive));
}
}
use of org.apache.phoenix.schema.LocalIndexDataColumnRef in project phoenix by apache.
the class ProjectionCompiler method projectAllIndexColumns.
private static void projectAllIndexColumns(StatementContext context, TableRef tableRef, boolean resolveColumn, List<Expression> projectedExpressions, List<ExpressionProjector> projectedColumns, List<? extends PDatum> targetColumns) throws SQLException {
ColumnResolver resolver = context.getResolver();
PTable index = tableRef.getTable();
int projectedOffset = projectedExpressions.size();
PhoenixConnection conn = context.getConnection();
PName tenantId = conn.getTenantId();
String tableName = index.getParentName().getString();
PTable dataTable = null;
try {
dataTable = conn.getTable(new PTableKey(tenantId, tableName));
} catch (TableNotFoundException e) {
if (tenantId != null) {
// Check with null tenantId
dataTable = conn.getTable(new PTableKey(null, tableName));
} else {
throw e;
}
}
int tableOffset = dataTable.getBucketNum() == null ? 0 : 1;
int minTablePKOffset = getMinPKOffset(dataTable, tenantId);
int minIndexPKOffset = getMinPKOffset(index, tenantId);
if (index.getIndexType() != IndexType.LOCAL) {
if (index.getColumns().size() - minIndexPKOffset != dataTable.getColumns().size() - minTablePKOffset) {
// We'll end up not using this by the optimizer, so just throw
String schemaNameStr = dataTable.getSchemaName() == null ? null : dataTable.getSchemaName().getString();
String tableNameStr = dataTable.getTableName() == null ? null : dataTable.getTableName().getString();
throw new ColumnNotFoundException(schemaNameStr, tableNameStr, null, WildcardParseNode.INSTANCE.toString());
}
}
for (int i = tableOffset, j = tableOffset; i < dataTable.getColumns().size(); i++) {
PColumn column = dataTable.getColumns().get(i);
// Skip tenant ID column (which may not be the first column, but is the first PK column)
if (SchemaUtil.isPKColumn(column) && j++ < minTablePKOffset) {
tableOffset++;
continue;
}
PColumn tableColumn = dataTable.getColumns().get(i);
String indexColName = IndexUtil.getIndexColumnName(tableColumn);
PColumn indexColumn = null;
ColumnRef ref = null;
try {
indexColumn = index.getColumnForColumnName(indexColName);
ref = new ColumnRef(tableRef, indexColumn.getPosition());
} catch (ColumnNotFoundException e) {
if (index.getIndexType() == IndexType.LOCAL) {
try {
ref = new LocalIndexDataColumnRef(context, indexColName);
indexColumn = ref.getColumn();
} catch (ColumnFamilyNotFoundException c) {
throw e;
}
} else {
throw e;
}
}
String colName = tableColumn.getName().getString();
String tableAlias = tableRef.getTableAlias();
if (resolveColumn) {
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();
expression = coerceIfNecessary(i - tableOffset + projectedOffset, targetColumns, expression);
// We do not need to check if the column is a viewConstant, because view constants never
// appear as a column in an index
projectedExpressions.add(expression);
boolean isCaseSensitive = !SchemaUtil.normalizeIdentifier(colName).equals(colName);
ExpressionProjector projector = new ExpressionProjector(colName, tableRef.getTableAlias() == null ? dataTable.getName().getString() : tableRef.getTableAlias(), expression, isCaseSensitive);
projectedColumns.add(projector);
}
}
use of org.apache.phoenix.schema.LocalIndexDataColumnRef in project phoenix by apache.
the class ExpressionCompiler method resolveColumn.
/**
* Called by visitor to resolve a column expression node into a column reference.
* Derived classes may use this as a hook to trap all column resolves.
* @param node a column expression node
* @return a resolved ColumnRef
* @throws SQLException if the column expression node does not refer to a known/unambiguous column
*/
protected ColumnRef resolveColumn(ColumnParseNode node) throws SQLException {
ColumnRef ref = null;
try {
ref = context.getResolver().resolveColumn(node.getSchemaName(), node.getTableName(), node.getName());
} catch (ColumnNotFoundException e) {
// operation given that we know the join is local.
if (context.getCurrentTable().getTable().getIndexType() == IndexType.LOCAL) {
try {
return new LocalIndexDataColumnRef(context, node.getName());
} catch (ColumnFamilyNotFoundException c) {
throw e;
}
} else {
throw e;
}
}
PTable table = ref.getTable();
int pkPosition = ref.getPKSlotPosition();
// Disallow explicit reference to salting column, tenant ID column, and index ID column
if (pkPosition >= 0) {
boolean isSalted = table.getBucketNum() != null;
boolean isMultiTenant = context.getConnection().getTenantId() != null && table.isMultiTenant();
boolean isSharedViewIndex = table.getViewIndexId() != null;
int minPosition = (isSalted ? 1 : 0) + (isMultiTenant ? 1 : 0) + (isSharedViewIndex ? 1 : 0);
if (pkPosition < minPosition) {
throw new ColumnNotFoundException(table.getSchemaName().getString(), table.getTableName().getString(), null, ref.getColumn().getName().getString());
}
}
return ref;
}
Aggregations