Search in sources :

Example 1 with OrderByNode

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

the class SubselectRewriter method flatten.

private SelectStatement flatten(SelectStatement select, SelectStatement subselect) throws SQLException {
    // Replace aliases in sub-select first.
    subselect = ParseNodeRewriter.rewrite(subselect, this);
    ParseNode whereRewrite = subselect.getWhere();
    List<ParseNode> groupByRewrite = subselect.getGroupBy();
    ParseNode havingRewrite = subselect.getHaving();
    List<OrderByNode> orderByRewrite = subselect.getOrderBy();
    LimitNode limitRewrite = subselect.getLimit();
    OffsetNode offsetRewrite = subselect.getOffset();
    HintNode hintRewrite = subselect.getHint();
    boolean isDistinctRewrite = subselect.isDistinct();
    boolean isAggregateRewrite = subselect.isAggregate();
    ParseNode where = select.getWhere();
    if (where != null) {
        if (subselect.getLimit() != null || (subselect.isAggregate() && subselect.getGroupBy().isEmpty())) {
            return select;
        }
        ParseNode postFilter = where.accept(this);
        if (subselect.getGroupBy().isEmpty()) {
            whereRewrite = whereRewrite == null ? postFilter : NODE_FACTORY.and(Arrays.<ParseNode>asList(whereRewrite, postFilter));
        } else {
            havingRewrite = havingRewrite == null ? postFilter : NODE_FACTORY.and(Arrays.<ParseNode>asList(havingRewrite, postFilter));
        }
    }
    if (select.isDistinct()) {
        if (subselect.getLimit() != null || subselect.isAggregate() || subselect.isDistinct()) {
            return select;
        }
        isDistinctRewrite = true;
        orderByRewrite = null;
    }
    if (select.isAggregate()) {
        if (subselect.getLimit() != null || subselect.isAggregate() || subselect.isDistinct()) {
            return select;
        }
        isAggregateRewrite = true;
        orderByRewrite = null;
    }
    List<ParseNode> groupBy = select.getGroupBy();
    if (!groupBy.isEmpty()) {
        if (subselect.getLimit() != null || subselect.isAggregate() || subselect.isDistinct()) {
            return select;
        }
        groupByRewrite = Lists.<ParseNode>newArrayListWithExpectedSize(groupBy.size());
        for (ParseNode node : groupBy) {
            groupByRewrite.add(node.accept(this));
        }
        if (select.getHaving() != null) {
            havingRewrite = select.getHaving().accept(this);
        }
        orderByRewrite = null;
    }
    List<AliasedNode> selectNodes = select.getSelect();
    List<AliasedNode> selectNodesRewrite = Lists.newArrayListWithExpectedSize(selectNodes.size());
    for (AliasedNode aliasedNode : selectNodes) {
        ParseNode node = aliasedNode.getNode();
        if (node instanceof WildcardParseNode || (node instanceof TableWildcardParseNode && ((TableWildcardParseNode) node).getTableName().equals(tableAlias))) {
            for (AliasedNode aNode : subselect.getSelect()) {
                String alias = aNode.getAlias();
                String aliasRewrite = alias == null ? null : SchemaUtil.getColumnName(tableAlias, alias);
                selectNodesRewrite.add(NODE_FACTORY.aliasedNode(aliasRewrite, aNode.getNode()));
            }
        } else {
            selectNodesRewrite.add(NODE_FACTORY.aliasedNode(aliasedNode.getAlias(), node.accept(this)));
        }
    }
    List<OrderByNode> orderBy = select.getOrderBy();
    if (!orderBy.isEmpty()) {
        if (subselect.getLimit() != null) {
            return select;
        }
        orderByRewrite = Lists.newArrayListWithExpectedSize(orderBy.size());
        for (OrderByNode orderByNode : orderBy) {
            ParseNode node = orderByNode.getNode();
            orderByRewrite.add(NODE_FACTORY.orderBy(node.accept(this), orderByNode.isNullsLast(), orderByNode.isAscending()));
        }
    }
    OffsetNode offset = select.getOffset();
    if (offsetRewrite != null || (limitRewrite != null && offset != null)) {
        return select;
    } else {
        offsetRewrite = offset;
    }
    LimitNode limit = select.getLimit();
    if (limit != null) {
        if (limitRewrite == null) {
            limitRewrite = limit;
        } else {
            Integer limitValue = LimitCompiler.compile(null, select);
            Integer limitValueSubselect = LimitCompiler.compile(null, subselect);
            if (limitValue != null && limitValueSubselect != null) {
                limitRewrite = limitValue < limitValueSubselect ? limit : limitRewrite;
            } else {
                return select;
            }
        }
    }
    HintNode hint = select.getHint();
    if (hint != null) {
        hintRewrite = hintRewrite == null ? hint : HintNode.combine(hint, hintRewrite);
    }
    SelectStatement stmt = NODE_FACTORY.select(subselect.getFrom(), hintRewrite, isDistinctRewrite, selectNodesRewrite, whereRewrite, groupByRewrite, havingRewrite, orderByRewrite, limitRewrite, offsetRewrite, select.getBindCount(), isAggregateRewrite, select.hasSequence(), select.getSelects(), select.getUdfParseNodes());
    if (tableAlias != null) {
        this.removeAlias = true;
        stmt = ParseNodeRewriter.rewrite(stmt, this);
    }
    return stmt;
}
Also used : OffsetNode(org.apache.phoenix.parse.OffsetNode) TableWildcardParseNode(org.apache.phoenix.parse.TableWildcardParseNode) OrderByNode(org.apache.phoenix.parse.OrderByNode) WildcardParseNode(org.apache.phoenix.parse.WildcardParseNode) TableWildcardParseNode(org.apache.phoenix.parse.TableWildcardParseNode) AliasedNode(org.apache.phoenix.parse.AliasedNode) SelectStatement(org.apache.phoenix.parse.SelectStatement) LimitNode(org.apache.phoenix.parse.LimitNode) HintNode(org.apache.phoenix.parse.HintNode) WildcardParseNode(org.apache.phoenix.parse.WildcardParseNode) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) TableWildcardParseNode(org.apache.phoenix.parse.TableWildcardParseNode) ParseNode(org.apache.phoenix.parse.ParseNode)

Example 2 with OrderByNode

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

the class JoinCompiler method compile.

public static JoinTable compile(PhoenixStatement statement, SelectStatement select, ColumnResolver resolver) throws SQLException {
    JoinCompiler compiler = new JoinCompiler(statement, select, resolver);
    JoinTableConstructor constructor = compiler.new JoinTableConstructor();
    Pair<Table, List<JoinSpec>> res = select.getFrom().accept(constructor);
    JoinTable joinTable = res.getSecond() == null ? compiler.new JoinTable(res.getFirst()) : compiler.new JoinTable(res.getFirst(), res.getSecond());
    if (select.getWhere() != null) {
        joinTable.addFilter(select.getWhere());
    }
    ColumnRefParseNodeVisitor generalRefVisitor = new ColumnRefParseNodeVisitor(resolver, statement.getConnection());
    ColumnRefParseNodeVisitor joinLocalRefVisitor = new ColumnRefParseNodeVisitor(resolver, statement.getConnection());
    ColumnRefParseNodeVisitor prefilterRefVisitor = new ColumnRefParseNodeVisitor(resolver, statement.getConnection());
    joinTable.pushDownColumnRefVisitors(generalRefVisitor, joinLocalRefVisitor, prefilterRefVisitor);
    for (AliasedNode node : select.getSelect()) {
        node.getNode().accept(generalRefVisitor);
    }
    if (select.getGroupBy() != null) {
        for (ParseNode node : select.getGroupBy()) {
            node.accept(generalRefVisitor);
        }
    }
    if (select.getHaving() != null) {
        select.getHaving().accept(generalRefVisitor);
    }
    if (select.getOrderBy() != null) {
        for (OrderByNode node : select.getOrderBy()) {
            node.getNode().accept(generalRefVisitor);
        }
    }
    compiler.columnNodes.putAll(joinLocalRefVisitor.getColumnRefMap());
    compiler.columnNodes.putAll(generalRefVisitor.getColumnRefMap());
    for (ColumnRef ref : generalRefVisitor.getColumnRefMap().keySet()) {
        compiler.columnRefs.put(ref, ColumnRefType.GENERAL);
    }
    for (ColumnRef ref : joinLocalRefVisitor.getColumnRefMap().keySet()) {
        if (!compiler.columnRefs.containsKey(ref))
            compiler.columnRefs.put(ref, ColumnRefType.JOINLOCAL);
    }
    return joinTable;
}
Also used : PTable(org.apache.phoenix.schema.PTable) ComparisonParseNode(org.apache.phoenix.parse.ComparisonParseNode) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) AndParseNode(org.apache.phoenix.parse.AndParseNode) TableWildcardParseNode(org.apache.phoenix.parse.TableWildcardParseNode) EqualParseNode(org.apache.phoenix.parse.EqualParseNode) ParseNode(org.apache.phoenix.parse.ParseNode) OrderByNode(org.apache.phoenix.parse.OrderByNode) List(java.util.List) ArrayList(java.util.ArrayList) ColumnRef(org.apache.phoenix.schema.ColumnRef) LocalIndexDataColumnRef(org.apache.phoenix.schema.LocalIndexDataColumnRef) AliasedNode(org.apache.phoenix.parse.AliasedNode)

Example 3 with OrderByNode

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

the class SubselectRewriter method isOrderByPrefix.

/**
 * check if rewrittenNewOrderByNodes is prefix of selectStatement's order by.
 * @param selectStatement
 * @param rewrittenNewOrderByNodes
 * @return
 */
private boolean isOrderByPrefix(SelectStatement selectStatement, List<OrderByNode> rewrittenNewOrderByNodes) {
    List<OrderByNode> existingOrderByNodes = selectStatement.getOrderBy();
    if (rewrittenNewOrderByNodes.size() > existingOrderByNodes.size()) {
        return false;
    }
    Iterator<OrderByNode> existingOrderByNodeIter = existingOrderByNodes.iterator();
    for (OrderByNode rewrittenNewOrderByNode : rewrittenNewOrderByNodes) {
        assert existingOrderByNodeIter.hasNext();
        OrderByNode existingOrderByNode = existingOrderByNodeIter.next();
        if (!existingOrderByNode.equals(rewrittenNewOrderByNode)) {
            return false;
        }
    }
    return true;
}
Also used : OrderByNode(org.apache.phoenix.parse.OrderByNode)

Example 4 with OrderByNode

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

the class SubselectRewriter method createAliasedNodesFromSubselect.

/**
 * create new aliasedNodes from subSelectStatement's select alias.
 * @param subSelectStatement
 * @param rewrittenOrderByNodes
 * @return
 */
private List<AliasedNode> createAliasedNodesFromSubselect(SelectStatement subSelectStatement, ArrayList<OrderByNode> rewrittenOrderByNodes) throws SQLException {
    List<AliasedNode> selectAliasedNodes = subSelectStatement.getSelect();
    List<AliasedNode> newSelectAliasedNodes = new ArrayList<AliasedNode>(selectAliasedNodes.size());
    Map<ParseNode, Integer> rewrittenOrderByParseNodeToIndex = new HashMap<ParseNode, Integer>(rewrittenOrderByNodes.size());
    for (int index = 0; index < rewrittenOrderByNodes.size(); index++) {
        OrderByNode rewrittenOrderByNode = rewrittenOrderByNodes.get(index);
        rewrittenOrderByParseNodeToIndex.put(rewrittenOrderByNode.getNode(), Integer.valueOf(index));
    }
    for (AliasedNode selectAliasedNode : selectAliasedNodes) {
        String selectAliasName = selectAliasedNode.getAlias();
        ParseNode oldSelectAliasParseNode = selectAliasedNode.getNode();
        if (selectAliasName == null) {
            selectAliasName = SchemaUtil.normalizeIdentifier(oldSelectAliasParseNode.getAlias());
        }
        // we must has alias for sum(code)
        if (selectAliasName == null) {
            throw new SQLExceptionInfo.Builder(SQLExceptionCode.SUBQUERY_SELECT_LIST_COLUMN_MUST_HAS_ALIAS).setMessage("the subquery is:" + subSelectStatement).build().buildException();
        }
        ColumnParseNode newColumnParseNode = NODE_FACTORY.column(null, selectAliasName, selectAliasName);
        Integer index = rewrittenOrderByParseNodeToIndex.get(oldSelectAliasParseNode);
        if (index != null) {
            // replace the rewrittenOrderByNode's child to newColumnParseNode
            OrderByNode oldOrderByNode = rewrittenOrderByNodes.get(index);
            rewrittenOrderByNodes.set(index, NODE_FACTORY.orderBy(newColumnParseNode, oldOrderByNode.isNullsLast(), oldOrderByNode.isAscending()));
        }
        AliasedNode newSelectAliasNode = NODE_FACTORY.aliasedNode(null, newColumnParseNode);
        newSelectAliasedNodes.add(newSelectAliasNode);
    }
    return newSelectAliasedNodes;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) OrderByNode(org.apache.phoenix.parse.OrderByNode) AliasedNode(org.apache.phoenix.parse.AliasedNode) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) WildcardParseNode(org.apache.phoenix.parse.WildcardParseNode) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) TableWildcardParseNode(org.apache.phoenix.parse.TableWildcardParseNode) ParseNode(org.apache.phoenix.parse.ParseNode) SQLExceptionInfo(org.apache.phoenix.exception.SQLExceptionInfo)

Example 5 with OrderByNode

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

Aggregations

OrderByNode (org.apache.phoenix.parse.OrderByNode)9 ParseNode (org.apache.phoenix.parse.ParseNode)8 ColumnParseNode (org.apache.phoenix.parse.ColumnParseNode)7 AliasedNode (org.apache.phoenix.parse.AliasedNode)6 TableWildcardParseNode (org.apache.phoenix.parse.TableWildcardParseNode)5 WildcardParseNode (org.apache.phoenix.parse.WildcardParseNode)5 ArrayList (java.util.ArrayList)3 AndParseNode (org.apache.phoenix.parse.AndParseNode)3 ComparisonParseNode (org.apache.phoenix.parse.ComparisonParseNode)3 SelectStatement (org.apache.phoenix.parse.SelectStatement)3 PTable (org.apache.phoenix.schema.PTable)3 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 SQLExceptionInfo (org.apache.phoenix.exception.SQLExceptionInfo)2 DerivedTableNode (org.apache.phoenix.parse.DerivedTableNode)2 EqualParseNode (org.apache.phoenix.parse.EqualParseNode)2 LiteralParseNode (org.apache.phoenix.parse.LiteralParseNode)2 TableNode (org.apache.phoenix.parse.TableNode)2 ColumnRef (org.apache.phoenix.schema.ColumnRef)2 LocalIndexDataColumnRef (org.apache.phoenix.schema.LocalIndexDataColumnRef)2