Search in sources :

Example 1 with BindTableNode

use of org.apache.phoenix.parse.BindTableNode in project phoenix by apache.

the class JoinCompiler method optimize.

public static SelectStatement optimize(PhoenixStatement statement, SelectStatement select, final ColumnResolver resolver) throws SQLException {
    TableRef groupByTableRef = null;
    TableRef orderByTableRef = null;
    if (select.getGroupBy() != null && !select.getGroupBy().isEmpty()) {
        ColumnRefParseNodeVisitor groupByVisitor = new ColumnRefParseNodeVisitor(resolver, statement.getConnection());
        for (ParseNode node : select.getGroupBy()) {
            node.accept(groupByVisitor);
        }
        Set<TableRef> set = groupByVisitor.getTableRefSet();
        if (set.size() == 1) {
            groupByTableRef = set.iterator().next();
        }
    } else if (select.getOrderBy() != null && !select.getOrderBy().isEmpty()) {
        ColumnRefParseNodeVisitor orderByVisitor = new ColumnRefParseNodeVisitor(resolver, statement.getConnection());
        for (OrderByNode node : select.getOrderBy()) {
            node.getNode().accept(orderByVisitor);
        }
        Set<TableRef> set = orderByVisitor.getTableRefSet();
        if (set.size() == 1) {
            orderByTableRef = set.iterator().next();
        }
    }
    JoinTable join = compile(statement, select, resolver);
    if (groupByTableRef != null || orderByTableRef != null) {
        QueryCompiler compiler = new QueryCompiler(statement, select, resolver, false);
        List<Object> binds = statement.getParameters();
        StatementContext ctx = new StatementContext(statement, resolver, new Scan(), new SequenceManager(statement));
        QueryPlan plan = compiler.compileJoinQuery(ctx, binds, join, false, false, null);
        TableRef table = plan.getTableRef();
        if (groupByTableRef != null && !groupByTableRef.equals(table)) {
            groupByTableRef = null;
        }
        if (orderByTableRef != null && !orderByTableRef.equals(table)) {
            orderByTableRef = null;
        }
    }
    final Map<TableRef, TableRef> replacement = new HashMap<TableRef, TableRef>();
    for (Table table : join.getTables()) {
        if (table.isSubselect())
            continue;
        TableRef tableRef = table.getTableRef();
        List<ParseNode> groupBy = tableRef.equals(groupByTableRef) ? select.getGroupBy() : null;
        List<OrderByNode> orderBy = tableRef.equals(orderByTableRef) ? select.getOrderBy() : null;
        SelectStatement stmt = getSubqueryForOptimizedPlan(select.getHint(), table.getDynamicColumns(), tableRef, join.getColumnRefs(), table.getPreFiltersCombined(), groupBy, orderBy, table.isWildCardSelect(), select.hasSequence(), select.getUdfParseNodes());
        QueryPlan plan = statement.getConnection().getQueryServices().getOptimizer().optimize(statement, stmt);
        if (!plan.getTableRef().equals(tableRef)) {
            replacement.put(tableRef, plan.getTableRef());
        }
    }
    if (replacement.isEmpty())
        return select;
    TableNode from = select.getFrom();
    TableNode newFrom = from.accept(new TableNodeVisitor<TableNode>() {

        private TableRef resolveTable(String alias, TableName name) throws SQLException {
            if (alias != null)
                return resolver.resolveTable(null, alias);
            return resolver.resolveTable(name.getSchemaName(), name.getTableName());
        }

        private TableName getReplacedTableName(TableRef tableRef) {
            String schemaName = tableRef.getTable().getSchemaName().getString();
            return TableName.create(schemaName.length() == 0 ? null : schemaName, tableRef.getTable().getTableName().getString());
        }

        @Override
        public TableNode visit(BindTableNode boundTableNode) throws SQLException {
            TableRef tableRef = resolveTable(boundTableNode.getAlias(), boundTableNode.getName());
            TableRef replaceRef = replacement.get(tableRef);
            if (replaceRef == null)
                return boundTableNode;
            String alias = boundTableNode.getAlias();
            return NODE_FACTORY.bindTable(alias == null ? null : '"' + alias + '"', getReplacedTableName(replaceRef));
        }

        @Override
        public TableNode visit(JoinTableNode joinNode) throws SQLException {
            TableNode lhs = joinNode.getLHS();
            TableNode rhs = joinNode.getRHS();
            TableNode lhsReplace = lhs.accept(this);
            TableNode rhsReplace = rhs.accept(this);
            if (lhs == lhsReplace && rhs == rhsReplace)
                return joinNode;
            return NODE_FACTORY.join(joinNode.getType(), lhsReplace, rhsReplace, joinNode.getOnNode(), joinNode.isSingleValueOnly());
        }

        @Override
        public TableNode visit(NamedTableNode namedTableNode) throws SQLException {
            TableRef tableRef = resolveTable(namedTableNode.getAlias(), namedTableNode.getName());
            TableRef replaceRef = replacement.get(tableRef);
            if (replaceRef == null)
                return namedTableNode;
            String alias = namedTableNode.getAlias();
            return NODE_FACTORY.namedTable(alias == null ? null : '"' + alias + '"', getReplacedTableName(replaceRef), namedTableNode.getDynamicColumns());
        }

        @Override
        public TableNode visit(DerivedTableNode subselectNode) throws SQLException {
            return subselectNode;
        }
    });
    SelectStatement indexSelect = IndexStatementRewriter.translate(NODE_FACTORY.select(select, newFrom), resolver, replacement);
    for (TableRef indexTableRef : replacement.values()) {
        // replace expressions with corresponding matching columns for functional indexes
        indexSelect = ParseNodeRewriter.rewrite(indexSelect, new IndexExpressionParseNodeRewriter(indexTableRef.getTable(), indexTableRef.getTableAlias(), statement.getConnection(), indexSelect.getUdfParseNodes()));
    }
    return indexSelect;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) SQLException(java.sql.SQLException) OrderByNode(org.apache.phoenix.parse.OrderByNode) SelectStatement(org.apache.phoenix.parse.SelectStatement) BindTableNode(org.apache.phoenix.parse.BindTableNode) UDFParseNode(org.apache.phoenix.parse.UDFParseNode) ComparisonParseNode(org.apache.phoenix.parse.ComparisonParseNode) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) AndParseNode(org.apache.phoenix.parse.AndParseNode) WildcardParseNode(org.apache.phoenix.parse.WildcardParseNode) TableWildcardParseNode(org.apache.phoenix.parse.TableWildcardParseNode) EqualParseNode(org.apache.phoenix.parse.EqualParseNode) ParseNode(org.apache.phoenix.parse.ParseNode) PTable(org.apache.phoenix.schema.PTable) JoinTableNode(org.apache.phoenix.parse.JoinTableNode) TableName(org.apache.phoenix.parse.TableName) DerivedTableNode(org.apache.phoenix.parse.DerivedTableNode) TableNode(org.apache.phoenix.parse.TableNode) JoinTableNode(org.apache.phoenix.parse.JoinTableNode) NamedTableNode(org.apache.phoenix.parse.NamedTableNode) BindTableNode(org.apache.phoenix.parse.BindTableNode) DerivedTableNode(org.apache.phoenix.parse.DerivedTableNode) NamedTableNode(org.apache.phoenix.parse.NamedTableNode) Scan(org.apache.hadoop.hbase.client.Scan) IndexExpressionParseNodeRewriter(org.apache.phoenix.parse.IndexExpressionParseNodeRewriter) TableRef(org.apache.phoenix.schema.TableRef)

Example 2 with BindTableNode

use of org.apache.phoenix.parse.BindTableNode in project phoenix by apache.

the class QueryOptimizer method rewriteQueryWithIndexReplacement.

private static SelectStatement rewriteQueryWithIndexReplacement(final PhoenixConnection connection, final ColumnResolver resolver, final SelectStatement select, final Map<TableRef, TableRef> replacement) throws SQLException {
    TableNode from = select.getFrom();
    TableNode newFrom = from.accept(new TableNodeVisitor<TableNode>() {

        private TableRef resolveTable(String alias, TableName name) throws SQLException {
            if (alias != null)
                return resolver.resolveTable(null, alias);
            return resolver.resolveTable(name.getSchemaName(), name.getTableName());
        }

        private TableName getReplacedTableName(TableRef tableRef) {
            String schemaName = tableRef.getTable().getSchemaName().getString();
            return TableName.create(schemaName.length() == 0 ? null : schemaName, tableRef.getTable().getTableName().getString());
        }

        @Override
        public TableNode visit(BindTableNode boundTableNode) throws SQLException {
            TableRef tableRef = resolveTable(boundTableNode.getAlias(), boundTableNode.getName());
            TableRef replaceRef = replacement.get(tableRef);
            if (replaceRef == null)
                return boundTableNode;
            String alias = boundTableNode.getAlias();
            return FACTORY.bindTable(alias == null ? null : '"' + alias + '"', getReplacedTableName(replaceRef));
        }

        @Override
        public TableNode visit(JoinTableNode joinNode) throws SQLException {
            TableNode lhs = joinNode.getLHS();
            TableNode rhs = joinNode.getRHS();
            TableNode lhsReplace = lhs.accept(this);
            TableNode rhsReplace = rhs.accept(this);
            if (lhs == lhsReplace && rhs == rhsReplace)
                return joinNode;
            return FACTORY.join(joinNode.getType(), lhsReplace, rhsReplace, joinNode.getOnNode(), joinNode.isSingleValueOnly());
        }

        @Override
        public TableNode visit(NamedTableNode namedTableNode) throws SQLException {
            TableRef tableRef = resolveTable(namedTableNode.getAlias(), namedTableNode.getName());
            TableRef replaceRef = replacement.get(tableRef);
            if (replaceRef == null)
                return namedTableNode;
            String alias = namedTableNode.getAlias();
            return FACTORY.namedTable(alias == null ? null : '"' + alias + '"', getReplacedTableName(replaceRef), namedTableNode.getDynamicColumns(), namedTableNode.getTableSamplingRate());
        }

        @Override
        public TableNode visit(DerivedTableNode subselectNode) throws SQLException {
            return subselectNode;
        }
    });
    if (from == newFrom) {
        return select;
    }
    SelectStatement indexSelect = IndexStatementRewriter.translate(FACTORY.select(select, newFrom), resolver, replacement);
    for (TableRef indexTableRef : replacement.values()) {
        // replace expressions with corresponding matching columns for functional indexes
        indexSelect = ParseNodeRewriter.rewrite(indexSelect, new IndexExpressionParseNodeRewriter(indexTableRef.getTable(), indexTableRef.getTableAlias(), connection, indexSelect.getUdfParseNodes()));
    }
    return indexSelect;
}
Also used : SQLException(java.sql.SQLException) JoinTableNode(org.apache.phoenix.parse.JoinTableNode) TableName(org.apache.phoenix.parse.TableName) BindTableNode(org.apache.phoenix.parse.BindTableNode) SelectStatement(org.apache.phoenix.parse.SelectStatement) DerivedTableNode(org.apache.phoenix.parse.DerivedTableNode) TableNode(org.apache.phoenix.parse.TableNode) JoinTableNode(org.apache.phoenix.parse.JoinTableNode) NamedTableNode(org.apache.phoenix.parse.NamedTableNode) BindTableNode(org.apache.phoenix.parse.BindTableNode) DerivedTableNode(org.apache.phoenix.parse.DerivedTableNode) NamedTableNode(org.apache.phoenix.parse.NamedTableNode) IndexExpressionParseNodeRewriter(org.apache.phoenix.parse.IndexExpressionParseNodeRewriter) TableRef(org.apache.phoenix.schema.TableRef)

Aggregations

SQLException (java.sql.SQLException)2 BindTableNode (org.apache.phoenix.parse.BindTableNode)2 DerivedTableNode (org.apache.phoenix.parse.DerivedTableNode)2 IndexExpressionParseNodeRewriter (org.apache.phoenix.parse.IndexExpressionParseNodeRewriter)2 JoinTableNode (org.apache.phoenix.parse.JoinTableNode)2 NamedTableNode (org.apache.phoenix.parse.NamedTableNode)2 SelectStatement (org.apache.phoenix.parse.SelectStatement)2 TableName (org.apache.phoenix.parse.TableName)2 TableNode (org.apache.phoenix.parse.TableNode)2 TableRef (org.apache.phoenix.schema.TableRef)2 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 Scan (org.apache.hadoop.hbase.client.Scan)1 AndParseNode (org.apache.phoenix.parse.AndParseNode)1 ColumnParseNode (org.apache.phoenix.parse.ColumnParseNode)1 ComparisonParseNode (org.apache.phoenix.parse.ComparisonParseNode)1 EqualParseNode (org.apache.phoenix.parse.EqualParseNode)1 OrderByNode (org.apache.phoenix.parse.OrderByNode)1 ParseNode (org.apache.phoenix.parse.ParseNode)1