Search in sources :

Example 1 with DerivedTableNode

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

the class SubselectRewriter method flatten.

public static SelectStatement flatten(SelectStatement select, PhoenixConnection connection) throws SQLException {
    TableNode from = select.getFrom();
    while (from != null && from instanceof DerivedTableNode) {
        DerivedTableNode derivedTable = (DerivedTableNode) from;
        SelectStatement subselect = derivedTable.getSelect();
        if (subselect.isUnion())
            break;
        ColumnResolver resolver = FromCompiler.getResolverForQuery(subselect, connection);
        SubselectRewriter rewriter = new SubselectRewriter(resolver, subselect.getSelect(), derivedTable.getAlias());
        SelectStatement ret = rewriter.flatten(select, subselect);
        if (ret == select)
            break;
        select = ret;
        from = select.getFrom();
    }
    return select;
}
Also used : SelectStatement(org.apache.phoenix.parse.SelectStatement) DerivedTableNode(org.apache.phoenix.parse.DerivedTableNode) TableNode(org.apache.phoenix.parse.TableNode) DerivedTableNode(org.apache.phoenix.parse.DerivedTableNode)

Example 2 with DerivedTableNode

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

the class SubselectRewriter method applyOrderBy.

private SelectStatement applyOrderBy(SelectStatement subselectStatement, List<OrderByNode> newOrderByNodes, TableNode subselectAsTableNode) throws SQLException {
    ArrayList<OrderByNode> rewrittenNewOrderByNodes = Lists.<OrderByNode>newArrayListWithExpectedSize(newOrderByNodes.size());
    for (OrderByNode newOrderByNode : newOrderByNodes) {
        ParseNode parseNode = newOrderByNode.getNode();
        rewrittenNewOrderByNodes.add(NODE_FACTORY.orderBy(parseNode.accept(this), newOrderByNode.isNullsLast(), newOrderByNode.isAscending()));
    }
    // in these case,we can safely override subselect's orderBy
    if (subselectStatement.getLimit() == null || subselectStatement.getOrderBy() == null || subselectStatement.getOrderBy().isEmpty()) {
        return NODE_FACTORY.select(subselectStatement, rewrittenNewOrderByNodes);
    }
    //then subselectStatement no need to modify
    if (this.isOrderByPrefix(subselectStatement, rewrittenNewOrderByNodes)) {
        return subselectStatement;
    }
    //modify the subselect "(select id,code from tableName order by code limit 3) as a" to
    //"(select id,code from (select id,code from tableName order by code limit 3) order by id) as a"
    List<AliasedNode> newSelectAliasedNodes = createAliasedNodesFromSubselect(subselectStatement, rewrittenNewOrderByNodes);
    assert subselectAsTableNode instanceof DerivedTableNode;
    //set the subselect alias to null.
    subselectAsTableNode = NODE_FACTORY.derivedTable(null, ((DerivedTableNode) subselectAsTableNode).getSelect());
    return NODE_FACTORY.select(subselectAsTableNode, HintNode.EMPTY_HINT_NODE, false, newSelectAliasedNodes, null, null, null, rewrittenNewOrderByNodes, null, null, 0, false, subselectStatement.hasSequence(), Collections.<SelectStatement>emptyList(), subselectStatement.getUdfParseNodes());
}
Also used : DerivedTableNode(org.apache.phoenix.parse.DerivedTableNode) OrderByNode(org.apache.phoenix.parse.OrderByNode) WildcardParseNode(org.apache.phoenix.parse.WildcardParseNode) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) TableWildcardParseNode(org.apache.phoenix.parse.TableWildcardParseNode) ParseNode(org.apache.phoenix.parse.ParseNode) AliasedNode(org.apache.phoenix.parse.AliasedNode)

Example 3 with DerivedTableNode

use of org.apache.phoenix.parse.DerivedTableNode 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)

Aggregations

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