Search in sources :

Example 1 with TableNode

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

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

the class SubqueryRewriter method visitLeave.

@Override
public ParseNode visitLeave(ComparisonParseNode node, List<ParseNode> l) throws SQLException {
    boolean isTopNode = topNode == node;
    if (isTopNode) {
        topNode = null;
    }
    ParseNode secondChild = l.get(1);
    if (!(secondChild instanceof SubqueryParseNode)) {
        return super.visitLeave(node, l);
    }
    SubqueryParseNode subqueryNode = (SubqueryParseNode) secondChild;
    SelectStatement subquery = fixSubqueryStatement(subqueryNode.getSelectNode());
    String rhsTableAlias = ParseNodeFactory.createTempAlias();
    JoinConditionExtractor conditionExtractor = new JoinConditionExtractor(subquery, resolver, connection, rhsTableAlias);
    ParseNode where = subquery.getWhere() == null ? null : subquery.getWhere().accept(conditionExtractor);
    if (where == subquery.getWhere()) {
        // non-correlated comparison subquery, add LIMIT 2, expectSingleRow = true
        subquery = NODE_FACTORY.select(subquery, NODE_FACTORY.limit(NODE_FACTORY.literal(2)));
        subqueryNode = NODE_FACTORY.subquery(subquery, true);
        l = Lists.newArrayList(l.get(0), subqueryNode);
        node = NODE_FACTORY.comparison(node.getFilterOp(), l.get(0), l.get(1));
        return super.visitLeave(node, l);
    }
    ParseNode rhsNode = null;
    boolean isGroupby = !subquery.getGroupBy().isEmpty();
    boolean isAggregate = subquery.isAggregate();
    List<AliasedNode> aliasedNodes = subquery.getSelect();
    if (aliasedNodes.size() == 1) {
        rhsNode = aliasedNodes.get(0).getNode();
    } else {
        List<ParseNode> nodes = Lists.<ParseNode>newArrayListWithExpectedSize(aliasedNodes.size());
        for (AliasedNode aliasedNode : aliasedNodes) {
            nodes.add(aliasedNode.getNode());
        }
        rhsNode = NODE_FACTORY.rowValueConstructor(nodes);
    }
    List<AliasedNode> additionalSelectNodes = conditionExtractor.getAdditionalSelectNodes();
    List<AliasedNode> selectNodes = Lists.newArrayListWithExpectedSize(additionalSelectNodes.size() + 1);
    selectNodes.add(NODE_FACTORY.aliasedNode(ParseNodeFactory.createTempAlias(), rhsNode));
    selectNodes.addAll(additionalSelectNodes);
    if (!isAggregate) {
        subquery = NODE_FACTORY.select(subquery, subquery.isDistinct(), selectNodes, where);
    } else {
        List<ParseNode> groupbyNodes = Lists.newArrayListWithExpectedSize(additionalSelectNodes.size() + subquery.getGroupBy().size());
        for (AliasedNode aliasedNode : additionalSelectNodes) {
            groupbyNodes.add(aliasedNode.getNode());
        }
        groupbyNodes.addAll(subquery.getGroupBy());
        subquery = NODE_FACTORY.select(subquery, subquery.isDistinct(), selectNodes, where, groupbyNodes, true);
    }
    ParseNode onNode = conditionExtractor.getJoinCondition();
    TableNode rhsTable = NODE_FACTORY.derivedTable(rhsTableAlias, subquery);
    JoinType joinType = isTopNode ? JoinType.Inner : JoinType.Left;
    ParseNode ret = NODE_FACTORY.comparison(node.getFilterOp(), l.get(0), NODE_FACTORY.column(NODE_FACTORY.table(null, rhsTableAlias), selectNodes.get(0).getAlias(), null));
    tableNode = NODE_FACTORY.join(joinType, tableNode, rhsTable, onNode, !isAggregate || isGroupby);
    return ret;
}
Also used : SelectStatement(org.apache.phoenix.parse.SelectStatement) SubqueryParseNode(org.apache.phoenix.parse.SubqueryParseNode) TableNode(org.apache.phoenix.parse.TableNode) LiteralParseNode(org.apache.phoenix.parse.LiteralParseNode) AndParseNode(org.apache.phoenix.parse.AndParseNode) ExistsParseNode(org.apache.phoenix.parse.ExistsParseNode) SubqueryParseNode(org.apache.phoenix.parse.SubqueryParseNode) RowValueConstructorParseNode(org.apache.phoenix.parse.RowValueConstructorParseNode) CompoundParseNode(org.apache.phoenix.parse.CompoundParseNode) ComparisonParseNode(org.apache.phoenix.parse.ComparisonParseNode) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) InParseNode(org.apache.phoenix.parse.InParseNode) ParseNode(org.apache.phoenix.parse.ParseNode) JoinType(org.apache.phoenix.parse.JoinTableNode.JoinType) AliasedNode(org.apache.phoenix.parse.AliasedNode)

Example 3 with TableNode

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

the class SubqueryRewriter method visitLeave.

@Override
public ParseNode visitLeave(ExistsParseNode node, List<ParseNode> l) throws SQLException {
    boolean isTopNode = topNode == node;
    if (isTopNode) {
        topNode = null;
    }
    SubqueryParseNode subqueryNode = (SubqueryParseNode) l.get(0);
    SelectStatement subquery = fixSubqueryStatement(subqueryNode.getSelectNode());
    String rhsTableAlias = ParseNodeFactory.createTempAlias();
    JoinConditionExtractor conditionExtractor = new JoinConditionExtractor(subquery, resolver, connection, rhsTableAlias);
    ParseNode where = subquery.getWhere() == null ? null : subquery.getWhere().accept(conditionExtractor);
    if (where == subquery.getWhere()) {
        // non-correlated EXISTS subquery, add LIMIT 1
        subquery = NODE_FACTORY.select(subquery, NODE_FACTORY.limit(NODE_FACTORY.literal(1)));
        subqueryNode = NODE_FACTORY.subquery(subquery, false);
        node = NODE_FACTORY.exists(subqueryNode, node.isNegate());
        return super.visitLeave(node, Collections.<ParseNode>singletonList(subqueryNode));
    }
    List<AliasedNode> additionalSelectNodes = conditionExtractor.getAdditionalSelectNodes();
    List<AliasedNode> selectNodes = Lists.newArrayListWithExpectedSize(additionalSelectNodes.size() + 1);
    selectNodes.add(NODE_FACTORY.aliasedNode(ParseNodeFactory.createTempAlias(), LiteralParseNode.ONE));
    selectNodes.addAll(additionalSelectNodes);
    subquery = NODE_FACTORY.select(subquery, true, selectNodes, where);
    ParseNode onNode = conditionExtractor.getJoinCondition();
    TableNode rhsTable = NODE_FACTORY.derivedTable(rhsTableAlias, subquery);
    JoinType joinType = isTopNode ? (node.isNegate() ? JoinType.Anti : JoinType.Semi) : JoinType.Left;
    ParseNode ret = isTopNode ? null : NODE_FACTORY.isNull(NODE_FACTORY.column(NODE_FACTORY.table(null, rhsTableAlias), selectNodes.get(0).getAlias(), null), !node.isNegate());
    tableNode = NODE_FACTORY.join(joinType, tableNode, rhsTable, onNode, false);
    return ret;
}
Also used : SelectStatement(org.apache.phoenix.parse.SelectStatement) SubqueryParseNode(org.apache.phoenix.parse.SubqueryParseNode) TableNode(org.apache.phoenix.parse.TableNode) LiteralParseNode(org.apache.phoenix.parse.LiteralParseNode) AndParseNode(org.apache.phoenix.parse.AndParseNode) ExistsParseNode(org.apache.phoenix.parse.ExistsParseNode) SubqueryParseNode(org.apache.phoenix.parse.SubqueryParseNode) RowValueConstructorParseNode(org.apache.phoenix.parse.RowValueConstructorParseNode) CompoundParseNode(org.apache.phoenix.parse.CompoundParseNode) ComparisonParseNode(org.apache.phoenix.parse.ComparisonParseNode) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) InParseNode(org.apache.phoenix.parse.InParseNode) ParseNode(org.apache.phoenix.parse.ParseNode) JoinType(org.apache.phoenix.parse.JoinTableNode.JoinType) AliasedNode(org.apache.phoenix.parse.AliasedNode)

Example 4 with TableNode

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

the class JoinCompiler method getSubqueryForOptimizedPlan.

private static SelectStatement getSubqueryForOptimizedPlan(HintNode hintNode, List<ColumnDef> dynamicCols, TableRef tableRef, Map<ColumnRef, ColumnRefType> columnRefs, ParseNode where, List<ParseNode> groupBy, List<OrderByNode> orderBy, boolean isWildCardSelect, boolean hasSequence, Map<String, UDFParseNode> udfParseNodes) {
    String schemaName = tableRef.getTable().getSchemaName().getString();
    TableName tName = TableName.create(schemaName.length() == 0 ? null : schemaName, tableRef.getTable().getTableName().getString());
    List<AliasedNode> selectList = new ArrayList<AliasedNode>();
    if (isWildCardSelect) {
        selectList.add(NODE_FACTORY.aliasedNode(null, WildcardParseNode.INSTANCE));
    } else {
        for (ColumnRef colRef : columnRefs.keySet()) {
            if (colRef.getTableRef().equals(tableRef)) {
                ParseNode node = NODE_FACTORY.column(tName, '"' + colRef.getColumn().getName().getString() + '"', null);
                if (groupBy != null) {
                    node = NODE_FACTORY.function(CountAggregateFunction.NAME, Collections.singletonList(node));
                }
                selectList.add(NODE_FACTORY.aliasedNode(null, node));
            }
        }
    }
    String tableAlias = tableRef.getTableAlias();
    TableNode from = NODE_FACTORY.namedTable(tableAlias == null ? null : '"' + tableAlias + '"', tName, dynamicCols);
    return NODE_FACTORY.select(from, hintNode, false, selectList, where, groupBy, null, orderBy, null, null, 0, groupBy != null, hasSequence, Collections.<SelectStatement>emptyList(), udfParseNodes);
}
Also used : TableName(org.apache.phoenix.parse.TableName) ArrayList(java.util.ArrayList) 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) 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) ColumnRef(org.apache.phoenix.schema.ColumnRef) LocalIndexDataColumnRef(org.apache.phoenix.schema.LocalIndexDataColumnRef) AliasedNode(org.apache.phoenix.parse.AliasedNode)

Example 5 with TableNode

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

TableNode (org.apache.phoenix.parse.TableNode)11 SelectStatement (org.apache.phoenix.parse.SelectStatement)9 ParseNode (org.apache.phoenix.parse.ParseNode)8 AndParseNode (org.apache.phoenix.parse.AndParseNode)7 ColumnParseNode (org.apache.phoenix.parse.ColumnParseNode)7 ComparisonParseNode (org.apache.phoenix.parse.ComparisonParseNode)6 DerivedTableNode (org.apache.phoenix.parse.DerivedTableNode)6 AliasedNode (org.apache.phoenix.parse.AliasedNode)5 BindTableNode (org.apache.phoenix.parse.BindTableNode)5 JoinTableNode (org.apache.phoenix.parse.JoinTableNode)5 JoinType (org.apache.phoenix.parse.JoinTableNode.JoinType)5 NamedTableNode (org.apache.phoenix.parse.NamedTableNode)5 SubqueryParseNode (org.apache.phoenix.parse.SubqueryParseNode)5 CompoundParseNode (org.apache.phoenix.parse.CompoundParseNode)4 ExistsParseNode (org.apache.phoenix.parse.ExistsParseNode)4 InParseNode (org.apache.phoenix.parse.InParseNode)4 LiteralParseNode (org.apache.phoenix.parse.LiteralParseNode)4 RowValueConstructorParseNode (org.apache.phoenix.parse.RowValueConstructorParseNode)4 TableRef (org.apache.phoenix.schema.TableRef)4 EqualParseNode (org.apache.phoenix.parse.EqualParseNode)3