Search in sources :

Example 1 with LocalIndexDataColumnRef

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());
}
Also used : ArrayList(java.util.ArrayList) OrderByNode(org.apache.phoenix.parse.OrderByNode) FamilyWildcardParseNode(org.apache.phoenix.parse.FamilyWildcardParseNode) WildcardParseNode(org.apache.phoenix.parse.WildcardParseNode) AliasedNode(org.apache.phoenix.parse.AliasedNode) LocalIndexDataColumnRef(org.apache.phoenix.schema.LocalIndexDataColumnRef) PTable(org.apache.phoenix.schema.PTable) ProjectedColumn(org.apache.phoenix.schema.ProjectedColumn) PColumn(org.apache.phoenix.schema.PColumn) FamilyWildcardParseNode(org.apache.phoenix.parse.FamilyWildcardParseNode) FamilyWildcardParseNode(org.apache.phoenix.parse.FamilyWildcardParseNode) WildcardParseNode(org.apache.phoenix.parse.WildcardParseNode) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) ParseNode(org.apache.phoenix.parse.ParseNode) ColumnRef(org.apache.phoenix.schema.ColumnRef) LocalIndexDataColumnRef(org.apache.phoenix.schema.LocalIndexDataColumnRef) TableRef(org.apache.phoenix.schema.TableRef) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 2 with LocalIndexDataColumnRef

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));
    }
}
Also used : PhoenixConnection(org.apache.phoenix.jdbc.PhoenixConnection) PColumnFamily(org.apache.phoenix.schema.PColumnFamily) LocalIndexDataColumnRef(org.apache.phoenix.schema.LocalIndexDataColumnRef) PTable(org.apache.phoenix.schema.PTable) ColumnFamilyNotFoundException(org.apache.phoenix.schema.ColumnFamilyNotFoundException) PColumn(org.apache.phoenix.schema.PColumn) ColumnNotFoundException(org.apache.phoenix.schema.ColumnNotFoundException) KeyValueColumnExpression(org.apache.phoenix.expression.KeyValueColumnExpression) BaseTerminalExpression(org.apache.phoenix.expression.BaseTerminalExpression) Expression(org.apache.phoenix.expression.Expression) SingleCellColumnExpression(org.apache.phoenix.expression.SingleCellColumnExpression) ProjectedColumnExpression(org.apache.phoenix.expression.ProjectedColumnExpression) CoerceExpression(org.apache.phoenix.expression.CoerceExpression) LiteralExpression(org.apache.phoenix.expression.LiteralExpression) ColumnRef(org.apache.phoenix.schema.ColumnRef) LocalIndexDataColumnRef(org.apache.phoenix.schema.LocalIndexDataColumnRef) PTableKey(org.apache.phoenix.schema.PTableKey)

Example 3 with LocalIndexDataColumnRef

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);
    }
}
Also used : PhoenixConnection(org.apache.phoenix.jdbc.PhoenixConnection) LocalIndexDataColumnRef(org.apache.phoenix.schema.LocalIndexDataColumnRef) PTable(org.apache.phoenix.schema.PTable) ColumnFamilyNotFoundException(org.apache.phoenix.schema.ColumnFamilyNotFoundException) PColumn(org.apache.phoenix.schema.PColumn) TableNotFoundException(org.apache.phoenix.schema.TableNotFoundException) ColumnNotFoundException(org.apache.phoenix.schema.ColumnNotFoundException) KeyValueColumnExpression(org.apache.phoenix.expression.KeyValueColumnExpression) BaseTerminalExpression(org.apache.phoenix.expression.BaseTerminalExpression) Expression(org.apache.phoenix.expression.Expression) SingleCellColumnExpression(org.apache.phoenix.expression.SingleCellColumnExpression) ProjectedColumnExpression(org.apache.phoenix.expression.ProjectedColumnExpression) CoerceExpression(org.apache.phoenix.expression.CoerceExpression) LiteralExpression(org.apache.phoenix.expression.LiteralExpression) PName(org.apache.phoenix.schema.PName) ColumnRef(org.apache.phoenix.schema.ColumnRef) LocalIndexDataColumnRef(org.apache.phoenix.schema.LocalIndexDataColumnRef) AmbiguousColumnException(org.apache.phoenix.schema.AmbiguousColumnException) PTableKey(org.apache.phoenix.schema.PTableKey)

Example 4 with LocalIndexDataColumnRef

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;
}
Also used : ColumnNotFoundException(org.apache.phoenix.schema.ColumnNotFoundException) ColumnRef(org.apache.phoenix.schema.ColumnRef) LocalIndexDataColumnRef(org.apache.phoenix.schema.LocalIndexDataColumnRef) LocalIndexDataColumnRef(org.apache.phoenix.schema.LocalIndexDataColumnRef) ColumnFamilyNotFoundException(org.apache.phoenix.schema.ColumnFamilyNotFoundException) PTable(org.apache.phoenix.schema.PTable)

Aggregations

ColumnRef (org.apache.phoenix.schema.ColumnRef)4 LocalIndexDataColumnRef (org.apache.phoenix.schema.LocalIndexDataColumnRef)4 PTable (org.apache.phoenix.schema.PTable)4 ColumnFamilyNotFoundException (org.apache.phoenix.schema.ColumnFamilyNotFoundException)3 ColumnNotFoundException (org.apache.phoenix.schema.ColumnNotFoundException)3 PColumn (org.apache.phoenix.schema.PColumn)3 BaseTerminalExpression (org.apache.phoenix.expression.BaseTerminalExpression)2 CoerceExpression (org.apache.phoenix.expression.CoerceExpression)2 Expression (org.apache.phoenix.expression.Expression)2 KeyValueColumnExpression (org.apache.phoenix.expression.KeyValueColumnExpression)2 LiteralExpression (org.apache.phoenix.expression.LiteralExpression)2 ProjectedColumnExpression (org.apache.phoenix.expression.ProjectedColumnExpression)2 SingleCellColumnExpression (org.apache.phoenix.expression.SingleCellColumnExpression)2 PhoenixConnection (org.apache.phoenix.jdbc.PhoenixConnection)2 PTableKey (org.apache.phoenix.schema.PTableKey)2 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1 AliasedNode (org.apache.phoenix.parse.AliasedNode)1 ColumnParseNode (org.apache.phoenix.parse.ColumnParseNode)1